본문 바로가기
개발 언어/cpp

CPP explicit 키워드

by eeeun:) 2022. 4. 27.
반응형

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

 

기본기 다지기, explicit 키워드 - The Software Open World

기본기 다지기, explicit 키워드 이번에는 explicit 키워드에 대해 얘기해 보려고 합니다. 최근에 C++ 를 배우신 분들은 모르시겠지만 explicit 키워드는 C++의 첫번째 표준안인 98년 9월 1일 버전에 처음

opensw.wikidot.com

 

728x90

댓글