반응형
c++ 98에 처음 도입된 키워드!
암시적 형 변환의 특성 때문에 프로그래머가 예상치 못하는 형 변환이 일어남으로 인해 정말 어려운 버그가 생기는 걸 방지하기 위해 도입된 키워드.
도대체 형 변환으로 정말 어려운 버그가 어떻게 생기는 걸까?
밑의 예제를 보자.
template <typename T>
struct Print {
void operator() (T v) {
cout << v << " ";
}
};
class Stack {
private:
vector<int> _data;
int _pos;
public:
const static int MIN_ELEM = 10;
// 최대 n개 요소를 가질 수 있는 Stack 생성자
Stack(int n = MIN_ELEM): _data(n), _pos(0) {
cout << "Stack(int) called" << endl;
}
// Stack& other 복사 생성자
Stack(const Stack& other): _data(other._data), _pos(other._pos) {
cout << "Stack(const Stack&) called" << endl;
}
// (int arr[], int n) 생성자
Stack(int arr[], int n): _data(arr, arr+n), _pos(n) {
cout << "Stack(int[], int) called" << endl;
}
// vector<int> 복사 생성자
Stack(vector<int> v): _data(v), _pos(v.size()) {
cout << "Stack(vector<int>) called" << endl;
}
void printAll() {
for_each (_data.begin(), _data.end(), Print<int>());
cout << endl;
}
};
int main(void)
{
Stack s1;
s1.printAll();
Stack s2(20);
s2.printAll();
Stack s3(s2);
vector<int> v(10, 3);
for_each(v.begin(), v.end(), Print<int>());
cout << endl;
Stack s4(v);
Stack s5 = v;
s1 = v;
s2 = 10;
s1.printAll();
s2.printAll();
}
실행 결과
Stack(int) called
0 0 0 0 0 0 0 0 0 0
Stack(int) called
0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
Stack(const Stack&) called
3 3 3 3 3 3 3 3 3 3
Stack(vector<int>) called
Stack(vector<int>) called
Stack(vector<int>) called
seungoh@c3r4s7 ft_containers % g++ a.cpp
seungoh@c3r4s7 ft_containers % ./a.out
Stack(int) called
0 0 0 0 0 0 0 0 0 0
Stack(int) called
0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
Stack(const Stack&) called
3 3 3 3 3 3 3 3 3 3
Stack(vector<int>) called
Stack(vector<int>) called
Stack(vector<int>) called
Stack(int) called
3 3 3 3 3 3 3 3 3 3
0 0 0 0 0 0 0 0 0 0
main 문 안의 s2= 10은 이상한 코드이다.
클래스에 int 값을 대입하는 것은 말이 안 된다.
하지만 우리의 c++ 컴파일은 어떻게든 컴파일을 시켜주려고 노력한다.
그래서 class의 생성자에 int 값이 들어가는 생성자를 찾아 그 생성자가 호출되도록 동작한다.
나는 클래스에 int값을 대입하니깐 당연히 컴파일이 안되고 오류를 반환할 것이라고 생각했는데, 실제로 c++ 컴파일러는 어떻게는 형 변환을 시켜 컴파일을 시켜준다.
이러한 경우를 막기 위해 우리는 explicit 키워드를 통해 컴파일러에게 형 변환을 금지시킨다고 알려줘야 한다.
explicit Stack(int n = MIN_ELEM): _data(n), _pos(0) {
cout << "Stack(int) called" << endl;
}
Reference
http://opensw.wikidot.com/cpp-fundamentals-explicit
728x90
'개발 언어 > cpp' 카테고리의 다른 글
CPP Lvalue, Rvalue, &&(우측값 레퍼런스) 개념 (0) | 2022.07.27 |
---|---|
CPP 4가지 타입 변환 연산자 (Casting) (0) | 2022.03.20 |
CPP template (0) | 2022.03.18 |
CPP 부모클래스에서 virtual 함수가 하나라도 있으면 소멸자도 무조건 virtual? (0) | 2022.03.10 |
:: Scope Operator(범위 지정 연산자)를 쓰는 3가지 상황 (0) | 2022.02.15 |
댓글