[C++기초] 3. 일부 새로운 C++ 기능
Index
Bool 데이터형
C의 경우
if(IsStudent() == 0)
{
// ...
}
if(IsStudent() == <non-zero>)
{
// ...
}
or
#define TRUE 1
#define FALSE 0
C++의 경우
if(IsStudent() == false)
{
// ...
}
if(Isstudent() == true)
{
// ...
}
참조(Reference)
- 포인터를 사용하는 좀 더 안전한 방법
- 하지만 Java만큼 제한적이지는 않음
- 원시 타입 : 값에 의한 복사
- 클래스 타입 : 참조에 의한 복사
- 포인터 연산이 없어도 될 때 안전하게 사용하기 위해 고안된 기능
값에 의한 호출 (C/Java/C#)
void swap(int arg1, int arg2)
{
int temp = arg1;
arg1 = arg2;
arg2 = temp;
}
int main()
{
int num1 = 10;
int num2 = 20;
swap (num1, num2);
}
참조에 의한 호출
void swap(int* arg1, int* arg2)
{
int temp = *arg1;
*arg1 = *arg2;
*arg2 = temp;
}
int main()
{
int num1 = 10;
int num2 = 20;
swap(&num1, &num2);
}
C++에서의 참조
-
별칭이다
int num = 100; int& reference = number;
- 포인터/주소랑은 전혀 다른 개념이다.
-
NULL이 될 수 없음
int & reference = NULL; //error
-
초기화 중에 반드시 선언되어야 함
int& reference = NULL; //error
-
참조하는 대상을 바꿀 수 없음
포인터 & 참조
포인터
void swap(int *number1, int*number2)
{
int temp = *number1;
*number1 = *number2;
*number2 = temp;
}
참조
void swap(int& number1, int& number2)
{
int temp = number1;
number1 = number2;
number2 = temp;
}
참조의 장점
- number1과 number2 변수는 NULL이 될 수 없음
- 우리가 소유하지 않은 메모리 장소를 가리킬 수 없음
컴퓨터는 참조가 뭐지 알까?
- 모름
- 포인터와 참조는 같은 어셈블리 명령어를 생성함
- 참조는 오직 인간을 위한 것임
- 컴파일러는 참조를 포인터로 바꿔줌. 기계가 이해할 수 있도록
기억할 점
- C에는 없지만 다른 언어에 있는 기능은 다른 엔지니어가 구현한 것이다!
참조와 관련된 코딩 표준
-
예시
struct Vector { int x; int y; int z; } bool TryDivide(Vector& a, Vector& b, Vector& c)
- 위의 경우 다음과 같이 헷갈릴 수 있다
a = b/c;
c = a/b;
- 위의 경우 다음과 같이 헷갈릴 수 있다
어떻게 해야 할까?
방법1
-
매개변수 이름을 더 잘 짓고 주석을 잘 달자!
bool TryDivide(Vector& result, Vector& a, Vector& b);
bool TryDivide(/*INOUT*/Vector & result,/*IN*/ Vecotr& a,/*IN*/ Vector& b)
#ifndef IN # define IN /* marks input param */ #endif #ifndef OUT # define OUT /* marks output param */ #endif #ifndef INOUT # define INOUT /* marks input+output param */ #endif bool TryDivide(INOUT Vector & result,IN Vecotr& a,IN Vector& b)
- 하지만 여전히 실수의 여지가 있음
방법2
-
읽기 전용 매개변수를 사용하자
vool TryDivide(Vector& result, const Vector& a, const Vector& b) const Vector a; const Vector b; vector result; TryDivide(a, b, result); // 컴파일 에러 TryDivide(result, a, b); // OK
-
하지만 호출자가
const
화를 시키지 않을 경우 문제가 생길 수 있음bool TryDivide(Vector& result,const Vector& a,const Vector& b); const Vector a; const Vector b; vector result; TryDivide(a, b, c); //어떤게 출력결과인가?
-
방법3
- 일부 코딩표준히 말하길
- 읽기 전용 매개변수르는 상수 포인터로 하라
출력 결과용 매개변수는 포인터로 하라
TryDivide(&a, b, c);
-
변수 a는 NULL이 될 수 있으나 이건 말이 안되는 경우가 종종 있음
TryDivide(NULL, b, c);
-
함수 내에 assert함수를 넣어 a가 NULL이 되는 경우를 잡자(또다른 코딩표준)
- assert(a);
- assert(a != NULL);
C#은 이걸 더 잘 고쳤음
-
out
키워드를 이용해서 고침bool TryDivide(out Vector result, ...);
- 안타깝게도, C++과 Java는 이걸 할 정도로 모던하지는 않음
- 그러므로 코딩 표준이 필요하다!