스토리텔링 개발자

[Effective C++] 4. 객체 초기화 문제 본문

개발/Effective C++

[Effective C++] 4. 객체 초기화 문제

김디트 2024. 5. 16. 10:48
728x90

항목 4. 객체를 사용하기 전에 반드시 그 객체를 초기화하자

 

 

 

자동으로 하는 객체 초기화의 문제
  • C++ 객체 초기화 규칙은 조금 복잡하다.
  • 그러므로 차라리 모든 객체를 사용하기 전에 초기화하는 것이 좋다.

 

 

 

초기화 시의 팁
  • 대입과 초기화를 헷갈리지 말자.
    • 대입 : 기본 생성자 호출 -> 복사 대입 연산자 호출
    • 초기화 리스트 사용 : 복사 생성자 호출 
    • 초기화란 생성자 본문이 실행되기 전에 되어야 하는 것이다.
    • 그러므로 멤버 초기화 리스트를 사용하자.
  • 클래스 멤버를 모두 초기화 리스트에 올리는 정책의 장점
    • 어떤 멤버가 초기화되지 않을 수 있다는 사실의 부담감이 없어진다.
  • 상수나 참조자 데이터 멤버는 대입이 불가능하다.
    • 즉, 반드시 초기화되어야 하므로 필수로 초기화 리스트에 넣어 주어야 한다.

 

 

 

객체를 구성하는 데이터의 초기화 순서
  • 이 순서는 컴파일러 상관 없이 동일하다.
  • 기본 클래스가 파생 클래스보다 먼저 초기화된다.
  • 클래스 데이터 멤버는 선언된 순서대로 초기화된다.
    • 멤버 초기화 리스트 순서와는 상관이 없다
    • 그러므로 초기화 리스트와 선언 순서를 맞춰주자.
  • 비지역 정적 객체의 초기화 순서는 개별 번역 단위에서 정해진다.

 

 

 

정적 객체
  • 정적 객체의 종류
    • 전역 객체
    • 네임 스페이스 유효범위에 정의된 객체
    • 클래스 내 static 객체
    • 함수 내 static 객체
    • 파일 유효범위에서 static 객체
  • 지역 / 비지역 정적 객체 구분
    • 지역 정적 객체(local static object) : 함수 내 정적객체
    • 비지역 정적 객체(non-local static object) : 나머지 정적 객체

 

 

 

번역 단위
  • 컴파일을 통해 하나의 목적 파일을 만드는 바탕이 되는 소스코드.
  • 기계어가 된 소스 파일 + #include 하는 파일(들))
  • 별개의 번역 단위에서 정의된 비지역 정적 객체들의 초기화 순서는 미정이다.

 

 

 

초기화 문제 
  • 비지역 정적 객체 
    • 싱글톤 패턴으로 만들어서 초기화를 명시적으로 처리해주면 해결 가능하다.
    • 비지역 정적 객체를 지역 정적 객체로 만든다.
      • 즉, 정적 객체를 함수 속으로 옮긴다. 
      • 지역 정적 객체는 함수 호출 중 그 객체 정의에 최초로 닿았을 때 초기화되므로 초기화 순서를 명확히 할 수 있다.
  • 지역 정적 객체
    • 다중 쓰레드에서 초기화 순서에 따른 미정의 문제가 발생 가능하다.
    • 다중 쓰레드 전 시동단계에서 참조자 반환 함수를 전부 손으로 불러주면 초기화와 관련된 경쟁상태가 없어진다.
  • 멤버가 아닌 기본 제공 타입(int 등)은 경우에 따라 초기화가 되기도 하고 안되기도 해서 직접! 꼭! 초기화해 주어야 한다.
728x90
Comments