일반적으로 변수를 초기화하는 경우는 아래의 세 가지 방법 중 하나를 사용합니다.
int i;
...
i = 10;
int i = 10;
int i = some_value; // some_value는 다른 변수 혹은 상수
위 세 가지 형태의 초기화 방법을 제외하고 표준에서 새롭게 보여주는 초기화 방법이 하나 더 있습니다.
int i(10);
int i(some_value); // some_value는 다른 변수 혹은 상수
위의 두 가지 구문입니다. int는 standard에서 제공하는 기본 변수형 중 하나입니다. 그런데 위에서는 int를 마치 클래스의 생성자를 초기화하듯이 사용하고 있습니다. 물론 클래스의 생성자 중에서 복사 생성자를 사용하는 것이겠지요.
위의 다섯 가지 변수 초기화 방법 중에서 가장 많이 사용되는 것은 아무래도 가장 처음 넣은 세 가지 방법이겠지요. 하지만 위에 나열한 다섯 가지 초기화 방법 외에도 하나 더 초기화하는 방법이 있습니다.
int i();
위 구문이 이상해 보이는 분도 계실 것입니다. 확실히 저도 이상하다고 보이니까요. 어쨋든 위의 방법도 초기화의 방법 중 하나입니다.
위 방법을 이용했을 경우 class의 변수였을 경우 기본 생성자가 호출되며, C++에서 제공하는 기본 타입의 변수의 경우 보통 0으로 초기화됩니다.
전혀 쓸모가 없다고 보실 분도 계시겠지만, C++ 표준 위원회는 쓸모없는 것은 남겨 두지 않습니다. 저것이 쓰이는 분야는 보통의 경우는 template을 사용하는 경우겠지요.
class 타입이 템플릿 타입 인자로 들어올지 아니면 기본형의 템플릿 타입 인자로 넘어 올런지는 아무도 모릅니다. 따라서 만약 기본형에 대하여 위의 구문이 불가능하다면 커다란 문제가 발생합니다. 예를 들면 어떤 템플릿 함수가 있습니다. 이 함수는 성공했을 경우는 성공한 값을 리턴하면 되지만 실패했을 경우 기본적인 값을 리턴해야 합니다. 그래서 함수가 실패를 해도 프로그램의 동작에는 영향을 미치지 않아야 합니다. 그래서 아래와 같은 함수를 만들었습니다.
template <typename T> T func(void)
{
T value;
...
if ( failed )
return T(); // 기본적인 값 == 클래스 생성 후 기본 생성자만 호출된 상태
else
return value;
}
자 위와 같은 함수를 만들었는데 템플릿 타입 인자로 int형이 들어갔다고 쳐보죠.
그러면 위 함수는 아래와 같이 변합니다.
int func(void)
{
int value;
...
if ( failed )
return int();
else
return value;
}
따라서 기본형에 대하여도 int i();와 같은 형태의 초기화 구문은 반드시 필요합니다. 기본형에는 사실상 생성자가 없습니다. 하지만 컴파일러가 생성자가 있는 것처럼 동작을 하게끔 만들어주는 방법은 필요합니다. template을 사용하지 않는다면 굳이 저런식으로 만들 필요는 없겠지만요. 이 사실을 알고 있기만 해도 나중에 template을 이용하여 어떤 클래스나 함수를 만들 때 많은 도움을 받을 수 있습니다.
'기본형에도 기본 생성자와 복사 생성자가 존재한다'
저술정보
- 자꾸 잊는 프로그래밍 이야기 4편
- 저자: 류인환(rihwan)
- 저술일: 2005년 9월 27일