struct BM {};
struct DM {};
struct Base
{
BM bm;
Base() : bm() {}
Base(int a) : bm() {}
~Base() { bm.~BM(); }
};
struct Derived : public Base
{
DM dm;
Derived() : Base(), dm() {}
Derived(int a) : Base(), dm() {}
~Derived() { dm.~DM(); ~Base(); }
};
생성자 호출 순서
1 기반 클래스 멤버의 생성자
2 기반 클래스의 생성자
3 파생 클래스 멤버의 생성자
4 파생 클래스의 생성자
(소멸자는 역순)
사용자가 생성자 호출 순서를 변경 불가
코드를 수정하여도 항상 기반 클래스 생성자가 먼저 호출되고 멤버 데이터의 생성자가 호출
컴파일러가 생성한 코드는 항상 디폴트 생성자를 호출
디폴트 생성자가 없는 경우 반드시 다른 생성자를 호출하는 코드를 작성해야함
class Buffer
{
public:
Buffer(std::size_t sz) { std::cout << "initialize buffer" << std::endl;}
void use() { std::cout << "use buffer" << std::endl;}
};
class Stream
{
public:
Stream(Buffer& buf) { buf.use();}
};
int main()
{
Buffer buf(1024);
Stream s(buf);
}
문제 없는 코드
...
class StreamWithBuffer : public Stream
{
Buffer buf{1024};
public:
StreamWithBuffer() : Stream(buf) {}
};
int main()
{
StreamWithBuffer swb;
}
기반 클래스에서 버퍼를 추가하면 멤버 데이터의 생성자보다 기반 클래스의 생성자가 먼저 불려
먼저 사용하고 이후 초기화해버리는 문제 발생
...
class StreamBuffer
{
protected:
Buffer buf{1024};
};
class StreamWithBuffer : public StreamBuffer,
public Stream
{
public:
StreamWithBuffer() : Stream(buf) {}
};
생성자 호출 문제를 해결하기 위하여 다중 상속 사용 - Base From Member (C++ IDioms)
별도 기반 클래스를 추가하고 먼저 상속받은 StreamBuffer의 생성자가 먼저 불림
class Base
{
public:
Base() { vfunc(); } // Base vfunc
void foo() { vfunc(); } // Derived vfunc
virtual void vfunc() { std::cout << "Base vfunc" << std::endl; }
};
class Derived : public Base
{
int data{10};
public:
virtual void vfunc() override
{
std::cout << "Derived vfunc : " << data << std::endl;
}
};
int main()
{
Derived d;
}