프로그래밍C++ 개발자

생성자를 선언할 때 'explicit'과 'implicit' 키워드의 차이점을 설명하고, 그 사용이 C++에서 객체 초기화에 미치는 영향을 설명하십시오.

Hintsage AI 어시스턴트로 면접 통과

답변

C++에서, 생성자가 하나의 인수로 호출될 수 있는 경우 기본적으로 implicit(암시적)으로 간주됩니다. 이러한 생성자는 암시적 타입 변환에 사용될 수 있습니다. 이를 방지하기 위해 explicit 키워드가 사용됩니다.

  • explicit 생성자는 암시적 변환을 금지합니다.

explicit를 사용하면, 예를 들어 함수에 타입이 일치하지 않는 인수를 전달하거나 변수를 초기화할 때 발생할 수 있는 예기치 않은 변환을 피할 수 있습니다.

예시:

struct Foo { explicit Foo(int x) { /* ... */ } }; Foo a = 10; // 오류, explicit는 암시적 초기화를 금지합니다. Foo b(10); // 괜찮음

explicit가 없었다면 Foo a = 10;이 허용되어 예기치 않은 버그로 이어질 수 있었습니다.

트릭 질문

질문: explicit으로 선언된 모든 생성자는 =로 초기화할 때 호출될 수 없습니다.
자주 하는 대답: 네, explicit는 모든 초기화를 금지합니다.
정답: explicit는 단지 암시적 변환만을 금지합니다. 직접 초기화(ClassName obj(param);)에서 explicit 생성자는 호출됩니다. 복사 초기화(ClassName obj = param;)에서는 호출되지 않습니다.

예시:

struct A { explicit A(int) {} }; A x = 1; // 오류 A y(1); // 괜찮음

주제에 대한 이해 부족으로 인한 실제 오류 사례


이야기: 프로젝트에서 explicit 없이 생성자를 작성하여 타입을 통해 초기화를 허용하였고, 이로 인해 함수 인수의 예기치 않은 자동 변환이 발생했습니다. 이로 인해 숨겨진 버그가 생기고 디버깅이 어려워졌습니다.



이야기: 개발자가 컨테이너 생성자에 대해 explicit를 설정하지 않아 기본 생성자가 다른 타입을 할당하거나 전달할 때 갑자기 호출되었습니다. 결과적으로 객체 생성 로직이 올바르지 않게 되면서 예측할 수 없는 행동이 발생했습니다.



이야기: 경험이 부족한 프로그래머가 explicit 생성자를 선언했지만, 직접 초기화에서 괄호를 사용하면 작동한다는 사실에 놀라워했습니다. 이는 편리하고 안전한 패턴을 사용하지 않게 만들고, 프로젝트에 불필요한 코드를 추가하게 했습니다.