본문 바로가기

C++

[C++] 변환 생성자의 묵시적 변환과 임시 객체 explicit

묵시적이란?

 

"직접적으로 말이나 행동으로 드러내지 않고 은연중에 뜻을 나타내 보이는. 또는 그런 것."

 

매개변수가 한 개인 생성자를 '변환 생성자(Conversion constructor)'라고 하는데 C++에서는 변환 생성자에서 묵시적으로 형변환이 일어나는 경우가 있다.

 

#include <iostream>
using namespace std;

class TestClass
{
public:
	TestClass(int param)
		: num(param)
	{
		cout << "TestClass(int)" << endl;
	}

private:
	int num = 0;
};

void TestFunc(const TestClass &tClass)
{
	cout << "TestFunc()" << endl;
}

int main()
{
	TestFunc(10);

	return 0;
}

 

결과값:

TestClass(int)
TestFunc()

 

결과가 예상과 다르다. 분명 TestFunc(10)으로 함수 호출만 했는데 성공적으로 컴파일이 되었고 객체를 생성하지 않았는데 객체가 생성되었다는 것이다.

 

이를 통해서 두 가지 사실을 알 수 있다.

 

int (10);	//C++에서는 가능
TestFunc(10);	//TestFunc(TestClass(10));과 같다.

 

첫 번째는 C++에서 변환 생성자에서 형변환이 일어난다는 점.

두 번째는 컴파일러가 자동으로 임시 객체를 생성한다는 것이다.

 

이러한 동작으로 불필요한 임시 객체로 인하여 프로그램의 효율을 떨어뜨릴 수 있다. 이러한 묵시적 변환 생성자가 사용자 모르게 호출될 가능성을 차단하기 위해서 explicit 예약어를 통해 해결할 수 있다.

 

#include <iostream>
using namespace std;

class TestClass
{
public:
	explicit TestClass(int param)	//explicit 예약어
		: num(param)
	{
		cout << "TestClass(int)" << endl;
	}

	operator int(void) { return num; }

private:
	int num = 0;
};

void TestFunc(const TestClass &tClass)
{
	cout << "TestFunc()" << endl;
}

int main()
{
	//TestFunc(10);	에러
 	TestFunc(TestClass(10));

	return 0;
}

 

explicit 예약어를 사용하자 TestFunc(10)은 허용되지 않는다. TestFunc(TestClass(10)) 처럼 명확히 기술해야 한다.