On this page
article
C++ Construct Object
생성 시 객체 초기화
컴파일러는 객체 생성 시 기반 클래스 및 멤버 데이터의 생성자를 호출하는 코드를 자동으로 생성.
주요 특징
- 사용자가 생성자 호출 순서를 변경할 수 없음
- 컴파일러가 생성한 코드는 항상 디폴트 생성자를 호출하므로, 디폴트 생성자가 없는 경우 명시적으로 생성자를 제공해야 함
- 실제 생성 코드는 Compiler Explorer에서 확인 가능
상속과 멤버 초기화 문제
기반 클래스의 생성자가 파생 클래스의 멤버 초기화보다 먼저 호출되어 발생하는 문제:
class Stream {
public:
Stream(Buffer& buf) {
buf.use();
}
};
// 문제 코드
class StreamWithBuffer : public Stream {
Buffer buf{1024}; // 기반 클래스 생성자가 먼저 호출되므로 초기화되지 않은 buf를 사용하게 됨
public:
StreamWithBuffer() : Stream(buf) {}
};
Base From Member 기법
다중 상속을 이용하여 위 문제를 해결하는 기법:
class StreamBuffer {
protected:
Buffer buf{1024};
};
class StreamWithBuffer : public StreamBuffer, public Stream {
public:
StreamWithBuffer() : Stream(buf) {}
// StreamBuffer의 생성자가 Stream보다 먼저 호출되므로 buf가 초기화됨
};
Initializer List
C++11에서 도입된 std::initializer_list
는 균일한 타입의 값 목록을 함수나 생성자에 전달하는 방법을 제공.
개념
const T
타입의 이름 없는 배열을 생성 후, 해당 메모리를 가리키는 객체- 읽기 전용으로 사용
- 함수, 생성자 인자로 많이 사용
- 사용 이유: 전달된 값의 개수를 쉽게 알 수 있음
생성자와 Initializer List
생성자가 std::initializer_list
를 인자로 받을 경우 특별한 규칙이 적용됩니다:
class Object {
public:
Object(int a, int b) { /* ... */ }
Object(std::initializer_list<int> list) { /* ... */ }
};
// Object(initializer_list) 생성자가 호출됨
Object o4{1, 2};
// initializer_list 객체를 배열처럼 초기화
std::initializer_list<int> list = {1, 2, 3, 4, 5};