Ответ 1
Foo f1;
Foo f2(f1);
Да, это будет делать то, что вы ожидаете от этого:
Вызывается конструктор копирования f2 Foo:: Foo (Foo const &).
Эта копия создает свой базовый класс, а затем каждый член (рекурсивно)
Если вы определяете класс следующим образом:
class X: public Y
{
private:
int m_a;
char* m_b;
Z m_c;
};
В вашем компиляторе будут определены следующие методы.
- Конструктор (по умолчанию) (2 версии)
- Конструктор (копирование)
- Деструктор (по умолчанию)
- Оператор присваивания
Конструктор: по умолчанию:
На самом деле существуют два стандартных конструктора.
Один используется для zero-initialization
, а другой используется для value-initialization
. Используется в зависимости от того, используете ли вы ()
во время инициализации или нет.
// Zero-Initialization compiler generated constructor
X::X()
:Y() // Calls the base constructor
// If this is compiler generated use
// the `Zero-Initialization version'
,m_a(0) // Default construction of basic PODS zeros them
,m_b(0) //
m_c() // Calls the default constructor of Z
// If this is compiler generated use
// the `Zero-Initialization version'
{
}
// Value-Initialization compiler generated constructor
X::X()
:Y() // Calls the base constructor
// If this is compiler generated use
// the `Value-Initialization version'
//,m_a() // Default construction of basic PODS does nothing
//,m_b() // The values are un-initialized.
m_c() // Calls the default constructor of Z
// If this is compiler generated use
// the `Value-Initialization version'
{
}
Примечания. Если базовый класс или любые члены не имеют допустимого видимого конструктора по умолчанию, конструктор по умолчанию не может быть сгенерирован. Это не ошибка, если ваш код не пытается использовать конструктор по умолчанию (тогда это только ошибка времени компиляции).
Конструктор (копирование)
X::X(X const& copy)
:Y(copy) // Calls the base copy constructor
,m_a(copy.m_a) // Calls each members copy constructor
,m_b(copy.m_b)
,m_c(copy.m_c)
{}
Примечания. Если базовый класс или любые члены не имеют допустимого конструктора видимой копии, конструктор копирования не может быть сгенерирован. Это не ошибка, если ваш код не пытается использовать конструктор копирования (тогда это только ошибка времени компиляции).
Оператор присваивания
X& operator=(X const& copy)
{
Y::operator=(copy); // Calls the base assignment operator
m_a = copy.m_a; // Calls each members assignment operator
m_b = copy.m_b;
m_c = copy.m_c;
return *this;
}
Примечания. Если базовый класс или любые члены не имеют действительного жизнеспособного оператора присваивания, то оператор присваивания не может быть сгенерирован. Это не ошибка, если ваш код не пытается использовать оператор присваивания (тогда это только ошибка времени компиляции).
Destructor
X::~X()
{
// First runs the destructor code
}
// This is psudo code.
// But the equiv of this code happens in every destructor
m_c.~Z(); // Calls the destructor for each member
// m_b // PODs and pointers destructors do nothing
// m_a
~Y(); // Call the base class destructor
- Если объявлен любой конструктор (включая копию), конструктор по умолчанию не реализуется компилятором.
- Если конструктор копирования объявлен, компилятор не будет генерировать его.
- Если оператор присваивания объявлен, то компилятор не будет генерировать его.
- Если объявлен деструктор, компилятор не будет генерировать его.
Глядя на ваш код, создаются следующие конструкторы копирования:
Foo::Foo(Foo const& copy)
:bar(copy.bar)
{}
Bar::Bar(Bar const& copy)
:i(copy.i)
,baz(copy.baz)
{}
Baz::Baz(Baz const& copy)
:j(copy.j)
{}