Object Creation

클래스 정의에서 객체 생성까지 이어지는 실제 초기화 경로

클래스를 선언했다는 것과 안전한 객체가 만들어진다는 것은 다르다. 멤버 초기화 순서, 기본값, 생성 위치가 모두 런타임 의미를 만든다.

01

멤버를 선언한다

객체가 직접 책임질 값만 멤버로 두고, 계산 가능한 값은 함수로 남긴다.

02

생성자 선택

기본 생성이 가능한 타입인지, 필수 값을 강제해야 하는 타입인지 먼저 나눈다.

03

위치 결정

지역 변수, unique_ptr, vector 원소 중 어디에 놓이는지에 따라 복사와 이동이 달라진다.

초기화 리스트
멤버가 바로 만들어진다 const 멤버와 참조 멤버는 초기화 리스트 없이는 만들 수 없다.
대입은 이미 생성된 뒤 값을 바꾸는 동작이다.
선언 순서
코드 순서보다 우선 초기화 리스트 순서가 아니라 클래스 안 멤버 선언 순서대로 초기화된다.
경고 옵션이 잡아 주는 대표 실수다.
explicit
암시 변환 차단 한 인자 생성자가 의도치 않은 변환 후보가 되는 일을 막는다.
도메인 타입일수록 explicit이 기본값에 가깝다.
생성 실패
예외와 부분 생성 생성자에서 예외가 나면 이미 생성된 멤버만 역순으로 파괴된다.
raw resource는 이 구간에서 특히 취약하다.

필수 값 · 순서 의존 · 생성 위치 점검

필수 값 객체가 의미 있으려면 반드시 필요한 값이 기본 생성으로 비어 있지 않은가.
순서 의존 한 멤버가 다른 멤버를 초기화에 참조한다면 선언 순서가 맞는가.
생성 위치 컨테이너에 넣을 객체가 복사 가능해야 하는지, 이동만 가능해도 되는지 확인한다.

초기화 순서

class User {
public:
    explicit User(std::string name) : name_(std::move(name)), size_(name_.size()) {}
private:
    std::string name_;
    std::size_t size_;
};