먼저 아래 따라오는 소스를 실행해 봅시다.
class TestClass { public: TestClass(int nParam = 1) : m_Num(nParam) { std::cout << "생성자 호출" << std::endl; } ~TestClass(){} private: int m_Num; }; void main() { TestClass TestObj1 = TestClass(1); TestClass TestObj2 = 2; TestClass TestObj3(3); TestObj1 = 4; }
결과가 어떤가요?
main()함수에서 클래스를 이용한 객체생성은 3번만 수행했으며 마지막 4번째 줄에서는 맨 처음 선언했던 객체에 직접 int형 정수를 넣어주고 있지만 VisualStudio2008 C++컴파일러의 입장에서는 아무런 오류없이 컴파일이 되고 실행또한 잘 됩니다. 하지만 특이한 점은 클래스로 생성한 객체는 3개지만, 실행해보면 "생성자 호출" 이라는 문자열이 4번 출력되죠. 이 부분으로 보면 분명히 생성자 함수는 4번 호출되었다는 것을 알 수 있습니다.
여기서 주목해야 할 부분은 main()함수의 2번째, 4번째 줄인
TestClass TestObj2 = 2; TestObj1 = 4;
이 부분입니다.
TestClass라는 클래스는 생성자의 매개변수로 int형 데이터를 받아오는 클래스로써 int형과 상호호환은 염두해두고 있지 않는 클래스입니다. 연산자 오버로딩도 하지 않았구요. 이 부분에 있어서 VisualStudio2008 C++컴파일러는 사용자의 편의를 위해 묵시적으로 변환하여 임시 객체 생성 후 해당 객체에 대입하게 됩니다.
explicit 키워드는 이럴 경우에 사용하는 것으로 명시적으로 생성자를 호출해야만 하는 상황이 아니면 절대 생성자를 호출해주지 않도록 해주는 것입니다. 그렇다면 똑같은 소스코드에 이 키워드를 삽입하면 어떻게 되는지 살펴보도록 하겠습니다.
아래의 소스를 보세요.
class TestClass { public: explicit TestClass(int nParam = 1) : m_Num(nParam) { std::cout << "생성자 호출" << std::endl; } ~TestClass(){} private: int m_Num; }; void main() { TestClass TestObj1 = TestClass(1); TestClass TestObj2 = 2; TestClass TestObj3(3); TestObj1 = 4; }