프로그래밍C++ 백엔드 개발자

C++에서 클래스 멤버 함수를 선언하고 정의하는 접근법에는 어떤 것이 있나요? 클래스 내부에서의 선언, 클래스 내부에서의 정의, 클래스 외부에서의 정의는 어떻게 다릅니까? 이것이 인라인 구현에 어떤 영향을 미칩니까?

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

답변.

C++에서 클래스 멤버 함수는 다음과 같이 선언할 수 있습니다:

  • 클래스 내부 (인라인 정의):

    class A { void foo() { /* ... */ } // 클래스 내부에 직접 };

    이러한 함수는 암묵적으로 inline으로 간주됩니다.

  • 클래스 내부 (단순 선언):

    class A { void foo(); // 단순 선언 }; void A::foo() { /* ... */ } // 클래스 외부에서의 정의

차이점:

  • 클래스 내부에서의 정의(«제자리에서»)는 자동으로 inline을 나타내며, 컴파일러는 이러한 함수를 호출 코드에 직접 삽입할 수 있습니다.
  • 클래스 외부에서의 정의는 명시적으로 지정하지 않는 한 자동으로 inline이 아닙니다(inline을 추가할 수는 있음):
    inline void A::foo() { /* ... */ }
  • 정의가 분리되는 경우 예를 들어 .cpp 파일에서 컴파일 시간을 단축하고 인터페이스와 구현을 분리하기 위해 클래스 외부에서의 선언이 필요합니다.

접근법의 장점과 단점:

  • 클래스 내부에서의 정의는 작고 자주 호출되는 함수에 유용합니다.
  • 큰 메서드나 별도로 수정되는 메서드의 경우, 클래스에서의 선언만 두고 .cpp 파일에서 정의하는 것이 더 효율적입니다.

덫이 있는 질문.

항상 클래스 내부에서 정의된 함수는 컴파일러에 의해 실제로 인라인으로 삽입됩니까?

답변: 아니요. inline 키워드(클래스 내부에서 정의될 때의 암묵적 할당 포함)는 컴파일러에 대한 단지 권장 사항일 뿐입니다. 컴파일러는 함수가 너무 복잡하거나 인라인으로 삽입하는 것이 바람직하지 않다고 판단할 경우 이 조언을 무시할 수 있습니다.


주제에 대한 세부 사항을 모르면 발생할 수 있는 실제 오류의 예.


이야기 1

큰 프로젝트에서 클래스 멤버 함수가 헤더 파일 안에 inline으로 정의되었고 수천 개의 번역 단위에 포함되어, 그 결과 컴파일 시간이 몇 배로 증가했고, 코드 중복으로 인해 바이너리 크기가 증가했습니다 — 컴파일러는 항상 동일한 기계 구현을 결합하지 않습니다.


이야기 2

실행 속도를 높이기 위해 개발자는 클래스의 모든 논리를 선언으로 옮겼습니다(예: .h 파일). 그 결과 함수가 변경될 때 전체 프로젝트가 리빌드 되었고, 실제로 통합에 영향을 미친 개별 파일만이 아닌 모든 파일이 재컴파일되었습니다.


이야기 3

팀의 새로운 구성원이 긴 직렬화 메서드와 파일 작업을 템플릿 클래스의 선언 안에 직접 넣어, 모든 TU에서의 오류 전파와 실행 파일 크기 증가를 초래했지만 성능 향상은 없었습니다.