기본기 다지기 , explicit 키워드 - The Software Open World 
 기본기 다지기 , explicit 키워드 
 이번 에 는 explicit 키워드 에 대해 얘기 해 보 려고 합니다 . 
 최근 에 C ++ 를 배우 신 분 들 은 모르 시 겠 지만 explicit 키워드 는 C ++ 의 첫 번 째 표준 안인 98 년 9 월 1 일 버전 에 처음 으로 도입 된 키워드 입니다 . Bjarne Stroustrup 이 처음 에 C ++ 를 창시 할 때 는 없 었 다는 거 죠 . 그럼 왜 98 년 C ++ 표준 안 을 출판 할 때 는 explicit 라는 키워드 를 넣 었 을까요 ? 이런 의문 을 제기 하 지 않 고 왜 그 런지 를 모른다면 C ++ 의 참맛 을 안다고 할 수 없 겠 죠 . 
 결 론 부터 말씀 드린다면 explicit 키워드 는 C 나 C ++ 의 공통 특징 중 의 하나 인 암시 적 형 변환 의 특성 때문 에 프로그래머 가 예상 치 못하 는 형 변환 이 일어남 으로 인해 정말 발견 하 기 어려운 버그 가 생기 는 걸 방지 하 기 위해서 도입 된 키워드 입니다 . 
 결론 은 그렇 다 치 는데 , 도대체 어떤 버그 이 길래 그렇게 발견 하 기 어려운 버그 일까요 ? 역시 백 마디 말 보다 하나 의 예 가 이해 를 돕 는 데 는 제격 이 므로 예 를 들 어 한 단계 씩 차분히 설명 해 보 도록 하 겠 습니다 . 
 일 단 , 여러분 이 Stack 이 라는 클래스 를 설계 하 려고 한다고 해 보 죠 . 제일 먼저 있 어야 할 것 은 Stack 객체 를 생성 하 는 생성자 가 있 어야 할 것 입니다 . 우선 생각 할 수 있 는 생성자 로 는 n 개 의 요소 까지 가질 수 있 는 Stack 을 생성 하 는 걸 생각 해 볼 수 있 을 것 입니다 . 다른 생성자 로 는 다른 Stack 을 복사 해서 생성 하 는 것 , 다른 배열 을 복사 해서 생성 하 는 것 , 다른 vector 를 복사 해서 생성 하 는 것 등 을 생각 할 수 있 을 것 입니다 . 이런 생성자 를 갖 는 Stack 은 다음 과 같이 작성 할 수 있 겠 네요 . 
 / / 저번 에 썼 던 코드 입니다 . 
 / / 최대 n 개 요소 를 가질 수 있 는 Stack 생성자 
 / / 기본 값 을 지정 해 봤 습니다 . 
 / / 다른 Stack 을 복사 해서 생성 하 는 복사 생성자 
 / / 다른 배열 을 복사 해서 생성 하 는 생성자 
 / / 다른 vector 를 복사 해서 생성 하 는 생성자 
 / / 그냥 어떻게 작동 하 는지 확인 하 기 위한 디버깅 용 멤버 함수 
 다음 코드 를 수행 하 면 어떤 결과 가 벌어질까요 ? 여러분 의 예상 과 맞 아 떨어지 는지 한 번 보 시 기 바랍니다 . 
 02 : main ( void ) 
 위 코드 가 컴파일 될까요 ? 특히 17 line 은 컴파일 이 안 될 것 같 지 않 으세요 ? stack 에 정수 값 을 할당 한다는 게 전혀 말 이 안 되 니 당연히 컴파일 안 되 어야 정상 이 겠 죠 . 자 한 번 컴파일 해 볼까요 ? 어 ! 이게 어떻게 된 거 죠 ? 아무런 에러 없이 컴파일 이 되 네요 . 17 line 도 에러 없이 컴파일 이 됩니다 . 이게 어떻게 된 조화 일까요 ? 컴파일러 가 왜 이걸 정상 적 인 코드 로 인식 하 고 컴파일 을 했 는지 를 알 려면 우리 의 입장 이 아니 라 컴파일러 의 입장 에서 생각 해 봐야 할 겁니다 . 이른바 역지사지 해 보 는 것 이 죠 . 
 17 line 을 만나 면 컴파일러 는 어떻 게 할까요 ? 컴파일러 가 하 는 일 은 자신 이 알 고 있 는 모든 지식 을 동원 해서 코드 를 컴파일 해내 는 것 입니다 . 먼저 s 2 에 정수 값 을 할당 할 수 있 는 할당 연산자 가 있 는지 볼 것 입니다 . 어 ! 그런데 Stack 클래스 정의 를 봤 더니 아무리 눈 씻 고 찾 아 봐도 없 네요 . 프로그래머 가 정의 한 할당 연산자 가 없 다면 , 컴파일러 가 생성 한 복사 할당 연산자 가 있 을 것 입니다 . 자기 가 생성 한 복사 할당 연산자 를 쓰 려고 했 더니 , 이번 에 는 10 이 라는 정수 값 이 복사 할당 연산자 의 인자 와 호환 이 되 질 않 네요 . 그렇 다고 우리 의 C ++ 컴파일러 는 그냥 컴파일 을 포기 하 고 항복 할 녀석 이 아니 죠 . 이번 에 는 혹시 정수 를 복사 할당 연산자 의 인자 ( const Stack & 일 겁니다 ) 로 변환 할 수 있 는지 를 볼 겁니다 . 여기 에서 C ++ 컴파일러 는 인자 가 하나 인 생성자 를 암시 적 형 변환 하 는 데 사용 한다는 것 을 기억 해 보 세요 . 죽 뒤져 보 았 더니 Stack ( int ) 가 눈 에 띄 네요 . 그래서 결국 Stack ( 10 ) 을 호출 해서 10 개 의 요소 를 갖 는 Stack 을 생성 하 고 그걸 복사 할당 연산자 를 이용 해서 s 2 에 할당 하 게 됩니다 . 이제 그 짧 은 코드 안 에서 어떤 일 이 일어나 는지 이해 가 되 시 나요 ? 
 제 가 쓰 고 있 는 컴파일러 ( Microsoft Visual C ++ 2005 ) 에서 컴파일 후 실행 해 봤 더니 다음 과 같 은 결과 가 나옵니다 . 
 01 : Stack ( int ) called / / 04 line 출력 
 02 : 0 0 0 0 0 0 0 0 0 0 / / 05 line 출력 
 03 : Stack ( int ) called / / 06 line 출력 
 04 : 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 / / 07 line 출력 
 05 : Stack ( const Stack &) called / / 08 line 출력 
 06 : 3 3 3 3 3 3 3 3 3 3 / / 10 line 출력 
 07 : Stack ( vector < int >) called / / 14 line 출력 
 08 : Stack ( vector < int >) called / / 15 line 출력 
 09 : Stack ( vector < int >) called / / 16 line 출력 
 10 : Stack ( int ) called / / 17 line 출력 
 11 : 3 3 3 3 3 3 3 3 3 3 / / 19 line 출력 
 12 : 0 0 0 0 0 0 0 0 0 0 / / 20 line 출력 
 C ++ 컴파일러 는 참 잘난 체 하 는 데 는 이골 이 났 나 봅니다 . 프로그래머 가 특별히 정의 하 지 않 더라도 기본 복사 생성자 , 복사 할 당자 를 생성 해 버리 고 , 그것 도 모자라 인자 가 하나 인 생성자 를 암시 적 형 변환 하 는데 지 맘대로 써 버린다니 … 그런데 나름 C ++ 컴파일러 도 말 못 할 고민 이 있 다고 하 네요 . C ++ 본래 태생 이 그래서 그렇 답니다 . 맘 에 안 든다고 버릴 수 도 없 고 , 그냥 우리 가 적응 해서 살 아야 되 지 않 겠 습니까 ? 
 그래서 , explicit 키워드 가 C ++ 의 첫 번 째 표준 안 에 새로 도입 됐 던 것 입니다 . explicit 키워드 는 인자 가 하나 인 생성자 가 암시 적 형 변환 에 쓰이 지 않 도록 해줍니다 . 암시 적 형 변환 에 쓰이 면 컴파일 에러 가 발생 하 게 됩니다 . 위 에 정의 한 Stack 정의 에서 다음 부분 을 수정 하 신 후 에 main ( ) 함수 를 다시 컴파일 해 보 시 기 바랍니다 . 
 제 가 쓰 는 컴파일러 에서 는 다음 과 같 은 에러 가 발생 하 네요 . 
 정확히 의도 한 바 와 같이 컴파일 에러 가 발생 하 네요 . 
 이 상 에서 밝힌 바 와 같이 explicit 키워드 는 C ++ 의 특징 중 에 하나 인 암시 적 형 변환 때문 에 발생 할 수 있 는 문제 의 소지 를 미리 예방 하 는데 유용 한 키워드 입니다 . 그러 니 , 클래스 의 생성자 를 설계 할 때 , 인자 가 하나 만 있 는 생성자 에 대해서 는 암시 적 형 변환 이 발생 할 때 어떤 일 이 벌어질지 를 생각 해 보 고 , 암시 적 형 변환 이 말 이 안 되 는 의미 를 갖 게 될 경우 explicit 라는 키워드 를 꼭 붙이 시 기 바랍니다 . 아니면 거꾸로 생성자 에 대해 일단 은 무조건 explicit 키워드 를 붙였 다가 컴파일 할 때 암시 적 형 변환 이 허용 되 지 않 아서 너무 불편 하 다 싶 으면 그때 가 서 빼 는 것 도 방법 입니다 . explicit 키워드 를 쓴 경우 에 는 다음 과 같이 코드 를 작성 하 시 면 암시 적 형 변환 과 같 은 의미 를 갖 는 코드 를 작성 하 실 수 있 습니다 . 
 마지막 으로 다음 을 기억 하 신다면 C ++ 의 암시 적 형 변환 때문 에 버그 찾 느라 헤메 는 일 은 없 을 것 입니다 . 
 생성자 에 explicit 키워드 를 써서 불 필요 한 암시 적 형 변환 을 막 아 두 자 . 
 궁금 이 ( guest ) 21 Apr 2016 08 : 20 
 Unfold by 궁금 이 ( guest ) , 21 Apr 2016 08 : 20 
 kitae ( guest ) 28 Sep 2016 04 : 42 
 쉽 고 이해 하 기 쉬운 설명 감사 합니다 . 
 Unfold by kitae ( guest ) , 28 Sep 2016 04 : 42 
 대단 하 십니다 ( guest ) 18 Jan 2017 14 : 20 
 이해 가 정말 잘 됩니다 . 개운 한 느낌 이 네요 ㅋㅋ ㅋㅋ 퍼 갈게요 ㅎㅎㅎ 
 Unfold by 대단 하 십니다 ( guest ) , 18 Jan 2017 14 : 20 
 감사 합니다 ( guest ) 07 Feb 2017 02 : 35 
 덕분 에 잘 이해 가 갑니다 . 출처 링크 를 밝히 고 공유 해 가 도 되 나요 ? 
 Unfold by 감사 합니다 ( guest ) , 07 Feb 2017 02 : 35 
 YoonSoo Kim 07 Feb 2017 02 : 46 
 예 ~ 공유 해 가 셔도 무방 합니다 . 
 Unfold 답변 드립니다 . by YoonSoo Kim , 07 Feb 2017 02 : 46 
 대단 해요 ! ( guest ) 12 Apr 2018 12 : 59 
 정말 감사 합니다 . 이해 가 너무 잘 되 네요 . 감사 합니다 ! 
 근데 정말 죄송 한데 헤더 를 알려 주 실 수 잇 을까요 … ? 한번 실제로 써 보 고 싶 어요 ! ! 
 Unfold by 대단 해요 ! ( guest ) , 12 Apr 2018 12 : 59 
 page revision : 2 , last edited : 19 Sep 2009 09 : 12