Home [C++] explicit
Post
Cancel

[C++] explicit

explicit 란?

explicit로 선언된 생성자는 암시적인 타입 변환을 수행하지 않게 된다.
(명시적인 타입 변환은 수행한다.)

사용하는 이유

프로그래머가 예상하지 못한 타입 변환을 막아준다.

예상하지 못한 타입 변환은 무엇일까?? 아래 코드를 확인해 보자


예제 코드(explicit 미사용)

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
#include <iostream>

class Test {
private:
    int _num;
public:
    Test();
    Test(int n);
    Test(const Test& rhs);
    Test& operator=(const Test& rhs);
    ~Test() = default;
    void Print() const;
};

Test::Test() {
    std::cout << "기본 생성자" << std::endl;
}
Test::Test(int n){
    _num = n;
    std::cout << "파라미터 n이 있는 생성자" << std::endl;
}

Test::Test(const Test& rhs) {
    this->_num = rhs._num;
    std::cout << "복사 생성자" << std::endl;
}

Test& Test::operator=(const Test& rhs) {
    this->_num = rhs._num;
    std::cout << "복사 대입 연산자" << std::endl;

    return *this;
}

void Test::Print() const {
    std::cout <<"_num 값: " << _num << std::endl;
}


int main()
{
    Test test;
    test = 10000;
    test.Print();
}

위 예제 코드를 실행해 보면 아래와 같이 출력되는 것을 볼 수 있다.

cpp-01

즉,
암시적으로 test = 10000에서 “파라미터 n이 있는 생성자”와 “복사 대입 연산자”가 발생한 것을 알 수 있다.

암시적으로 발생한 이유는
컴파일러가 test = 10000을 볼 때 Test 클래스의 생성자 중에서 정수형(10000) 파라미터를 가진 생성자가 있는지를 확인하고 해당하는 생성자가 존재한다면 해당하는 생성자를 호출해서 타입 변환을 진행하기 때문이다.

여기서
explicit를 사용하게 되면 어떻게 될까?


예제 코드(explicit 사용)

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
#include <iostream>

class Test {
private:
    int _num;
public:
    explicit Test();
    explicit Test(int n);
    explicit Test(const Test& rhs);
    Test& operator=(const Test& rhs);
    ~Test() = default;
    void Print() const;
};

Test::Test() {
    std::cout << "기본 생성자" << std::endl;
}
Test::Test(int n){
    _num = n;
    std::cout << "파라미터 n이 있는 생성자" << std::endl;
}

Test::Test(const Test& rhs) {
    this->_num = rhs._num;
    std::cout << "복사 생성자" << std::endl;
}

Test& Test::operator=(const Test& rhs) {
    this->_num = rhs._num;
    std::cout << "복사 대입 연산자" << std::endl;

    return *this;
}

void Test::Print() const {
    std::cout <<"_num 값: " << _num << std::endl;
}


int main()
{
    Test test;
    test = 10000;
    test.Print();
}

생성자에 explicit를 추가하면 아래와 같이 컴파일 에러가 발생한 것을 볼 수 있다.

cpp-02

즉,
explicit로 인해 암시적으로 타입 변환이 이루어지는 것을 막았기 때문에 에러가 발생했다는 것을 확인할 수 있다.

그러므로, explicit를 사용할 때는 명시적 형변환을 사용해야 한다.

explicit 사용에 따른 명시적 형변환

1
2
3
4
5
6
int main()
{
    Test test;
    test = Test(10000);	// 명시적 형변환
    test.Print();
}

결론

생성자를 암시적 타입 변환으로 사용해야 할 이유가 있는 것이 아니라면 explicit 를 사용하는 것이 좋다.

This post is licensed under CC BY 4.0 by the author.