[C++] 변환 생성자와 explicit

SuLee·2021년 10월 7일
0

C++

목록 보기
7/8

📌 변환 생성자와 explicit

변환 생성자는 매개변수가 기본 자료형 하나인 생성자를 말한다. 이 변환 생성자의 문제점은 사용자와 의도와 별개로 컴파일러가 암시적으로 호출할 수 있다는 점이다.

class Test {
private:
    int m_num;
    
public:
    Test() {}
    Test(int num) : m_num(num) {} // 변환 생성자
    Test(const Test& t) : m_num(t.m_num) {}
    
    int PrintNum() const { return m_num; }
};
 
void Func(Test t) { cout << t.PrintNum() << endl; }


int main() {
    Func(5);
}

위의 Func(5);에서 Func()는 매개변수가 Test 사용자 정의 타입이지만, 암시적으로 변환 생성자가 호출이 되어 아래와 같이 변환되어 컴파일된다.

Func(Test(5));

때문에 의도치 않은 인자를 전달했을 때도 컴파일러가 암시적 변환을 하여 컴파일 에러가 발생하지 않아 잘못된 부분을 찾기 힘들 수 있다.

이러한 현상을 막기 위해 존재하는 키워드가 explicit이다. explicit 키워드를 사용하면 원하지 않는 암시적 변환을 명시할 수 있다.

class Test {
private:
    int m_num;
    
public:
    Test() {}
    explicit Test(int num) : m_num(num) {} // 변환 생성자
    Test(const Test& t) : m_num(t.m_num) {}
    
    int PrintNum() const { return m_num; }
};
 
void Func(Test t) { cout << t.PrintNum() << endl; }


int main() {
    Func(5); // 컴파일 에러
}

Test 클래스의 Test(int num)explicit으로 선언하여 기본 자료형인 intTest로 변환하는 것을 막을 수 있다.

또한 해당 기본 자료형의 생성자가 복사 생성자로 호출되는 것을 막을 수 있다.

Test t = 5; // 컴파일 에러
Test t(5); // 가능

첫 번째의 경우는 5를 대입하는 것으로 받아들이기 때문에 복사 생성자가 호출되어 컴파일 에러가 발생하지만 두 번째의 경우와 같이 명시적으로 생성자를 호출하는 것은 가능하다.

0개의 댓글