[C++] explicit 키워드
목차
- 01. Intro
- 02. explicit 키워드
- 암시적 변환 vs 명시적 변환
- 생성자 - 암시적 변환
- 생성자 - 명시적 변환
- 변환 연산자 - 암시적 변환
- 변환 연산자 - 명시적 변환
- 03. 마무리
- 04. 연관 내용
01. Intro
오늘은 명시적 변환을 유도하는 [explict] 키워드에 대해 알아보겠습니다.
02. explicit 키워드
암시적 변환 vs 명시적 변환
변환을 할 때, 암시적 변환과 명시적 변환 두 종류가 있습니다.
암시적 변환
int i = 10;
long long ll = i;
암시적 변환은 위 코드처럼 서로 다른 타입이지만, 컴파일러가 자동으로 해당 타입에 맞게 변환합니다.
명시적 변환
int i = 10;
// 명시적 변환 1
long long ll = static_cast<long long>(i);
// 명시적 변환 2
ll = (long long)i;
명시적 변환은 위 코드처럼 사용자가 직접 어떤 타입으로 변환시킬지 코드로 작성하는 것을 말합니다.
explicit 키워드는 해당 함수가 명시적 변환으로만, 사용되도록 유도합니다.
이는 자동 변환을 방지해 안전성을 보장하고, 코드 가독성을 향상하기 위해 사용합니다.
주로, 생성자와 변환 연산자에서 사용합니다.
생성자 - 암시적 변환
#include <iostream>
using namespace std;
class Sport
{
public:
Sport(int x)
{
_num = x;
cout << "Sport 클래스 생성자의 _num : " << _num << endl;
}
int _num;
};
int main()
{
// 직접 생성
Sport sport1(100);
// 암시적 형변환
// sport2(200); 와 같음.
Sport sport2 = 200;
}

위 코드를 실행하면, 다음과 같은 결과가 나옵니다.
Sport sport2 = 200;
위 방식은 [Sport(int x)]생성자에 대해 암시적 변환을 진행한 코드입니다.
객체를 생성할 때, 생성자 함수의 형태를 맞춘 sport(200)처럼 작동합니다.

정말로 같은 의미인지 확인하기 위해 어셈블리어로 확인했습니다.
어셈블리어의 call 명령어를 보면, 직접 생성하는 경우와 암시적 변환으로 생성하는 것 모두, Sport 생성자 함수 메모리 위치가 같은 것을 확인할 수 있습니다.
생성자 - 명시적 변환
#include <iostream>
using namespace std;
class Sport
{
public:
// explicit 생성자
explicit Sport(int x)
{
_num = x;
cout << "Sport 클래스 생성자의 _num : " << _num << endl;
}
int _num;
};
int main()
{
// 직접 생성
Sport sport1(100);
// 암시적 형변환
// sport2(200); 와 같음.
// Sport sport2 = 200;
// 명시적 변환 1 : 복사 생성자 사용
Sport sport3 = Sport(300);
// 명시적 변환 2 : 중괄호 초기화 사용
Sport sport4{ 400 };
}

생성자에 explicit 키워드를 앞에 붙이는 경우, 암시적 변환인 [Sport sport2 = 200;] 코드를 더 이상 사용할 수 없습니다.
복사 생성자와 중괄호 초기화를 사용하는 방식도 명시적 변환입니다.
중괄호 초기화는 암시적 형 변환을 방지하는 용도로 C++11에서 도입된 기능이지만, 추후에 자세히 알아보도록 하겠습니다.
Sport sport3 = Sport(300);
// 먼저, 직접 생성을 한 뒤에 복사 생성자를 이용해서 가능
Sport temp = Sport(300);
Sport sport3 = temp;
[Sport sport3 = Sport(300);]의 코드가 명시적 변환인 이유는 복사 생성자를 사용하기 때문입니다.
위 코드를 분해하면, 아래 두 줄의 코드처럼 작동합니다.
먼저, 임의의 Sport 객체를 생성할 때, Sport(300)인 생성자를 호출합니다.
그리고, 임의의 Sport 객체를 sport3 객체에 복사 생성자를 통해 대입합니다.
변환 연산자 - 암시적 변환
#include <iostream>
using namespace std;
class Sport
{
public:
// explicit 생성자
explicit Sport(int x)
{
_num = x;
}
// 암시적 int 형변환
operator int() const
{
return _num;
}
int _num;
};
int main()
{
// 직접 생성
Sport sport1(100);
// Sport의 암시적 int 형변환 호출
// (operator int() 호출)
int num = sport1;
cout << num << endl;
}
위 코드를 실행하면, 다음과 같은 결과가 출력됩니다.

변환 연산자 - 명시적 변환
#include <iostream>
using namespace std;
class Sport
{
public:
// explicit 생성자
explicit Sport(int x)
{
_num = x;
}
// 명시적 int 형변환
explicit operator int() const
{
return _num;
}
int _num;
};
int main()
{
// 직접 생성
Sport sport1(100);
// Sport의 암시적 int 형변환 호출
// (operator int() 호출)
// int num = sport1;
// Sport의 명시적 int 형변환 호출
// (explicit operator int() 호출)
int num = static_cast<int>(sport1);
cout << num << endl;
}
위 코드를 실행하면, 다음과 같은 결과가 출력됩니다.

만약에, 암시적 변환인 [int num = sport1;]를 호출하려면, 아래와 같은 오류가 출력됩니다.

추가로 [int num = (int)(sport1);]의 형태도 명시적 변환이므로 사용할 수 있습니다.
예제 코드로는 int에 대해서 변환을 진행했지만, 다른 타입인 float나 double, bool 등에서도 사용 가능합니다.
03. 마무리
오늘은 explicit 키워드를 사용해, 명시적 변환에 대해서 알아봤습니다.
explicit 키워드를 사용한 명시적 변환은 생성자나 변환 연산자에서 자동 변환이 되어 잘못된 동작을 일으키는 경우를 방지하고자 사용합니다. 즉, 우리가 확실한 의도를 가진 변환만 수행할 수 있게 유도합니다. 이를 통해, 안전성이 보장됩니다.
04. 연관 내용
읽어주셔서 감사합니다.
틀린 내용 지적은 언제나 환영입니다!
'게임 개발 > C++' 카테고리의 다른 글
| [C++] 중괄호 초기화 - 1. 사용 용도 (0) | 2025.03.19 |
|---|---|
| [C++] auto 키워드 (0) | 2025.03.18 |
| [C++] static 키워드 (1) | 2025.03.16 |
| [C++] 부동소수점 (0) | 2025.03.15 |
| [C++] 전방 선언 (2) | 2025.03.13 |