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

  • C++ 객체 초기화 규칙이 조금 복잡. 그러므로 모든 객체를 사용하기 전에 초기화.

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

  • 객체를 구성하는 데이터의 초기화 순서(컴파일러 상관 없이 동일)
    1. 기본 클래스가 파생 클래스보다 먼저 초기화
    2. 클래스 데이터 멤버는 선언된 순서대로 초기화 -> 멤버 초기화 리스트 순서와는 상관 없이!(초기화 리스트와 선언 순서 맞춰주자.)
    3. 비지역 정적 객체의 초기화 순서는 개별 번역 단위에서 정해진다.
  • 정적 객체 : 전역 객체, 네임 스페이스 유효범위에 정의된 객체, 클래스 내 static 객체, 함수 내 static 객체, 파일 유효범위에서 static 객체
    • 함수 내 정적객체 : 지역 정적 객체(local static object)
    • 나머지 정적 객체 : 비지역 정적 객체(non-local static object)
  • 번역 단위 : 컴파일을 통해 하나의 목적 파일을 만드는 바탕이 되는 소스코드.(기계어가 된 소스 파일 + #include 하는 파일(들))
  • 별개의 번역 단위에서 정의된 비지역 정적 객체들의 초기화 순서는 미정!
    • 싱글톤 패턴으로 만들어서 해결 가능
    • 함수 속으로 비지역 정적 객체를 옮겨 지역 정적 객체를 만든다. 지역 정적 객체는 함수 호출 중 그 객체 정의에 최초로 닿았을 때 초기화된다.
  • 다중 쓰레드시 초기화 순서에 따른 미정의 문제를 방지하기 위해 참조자 반환 함수를 전부 손으로 불러주면 초기화와 관련된 경쟁상태가 없어진다.(다중 쓰레드 전 시동단계에서)
  • 멤버가 아닌 기본 제공 타입은 경우에 따라 초기화가 되기도 하고 안되기도 해서 직접! 꼭! 초기화해 주어야 한다.