Явные конструкторы копирования не вызывают конструкторы копирования для членов.
Когда вы вводите тело конструктора, каждый член этого класса будет инициализирован. То есть, как только вы доберетесь до {
, вы гарантированно, что все ваши члены были инициализированы.
Если не указано, члены по умолчанию инициализируются в порядке их появления в классе. (И если они не могут быть, программа плохо сформирована.) Поэтому, если вы определяете свой собственный конструктор копий, теперь вам нужно называть любые конструкторы экземпляров-членов по своему желанию.
Вот небольшая программа, которую можно скопировать и вставить куда-нибудь и возиться с:
#include <iostream>
class Foo {
public:
Foo() {
std::cout << "In Foo::Foo()" << std::endl;
}
Foo(const Foo& rhs) {
std::cout << "In Foo::Foo(const Foo&)" << std::endl;
}
};
class Bar {
public:
Bar() {
std::cout << "In Bar::Bar()" << std::endl;
}
Bar(const Bar& rhs) {
std::cout << "In Bar::Bar(const Bar&)" << std::endl;
}
};
class Baz {
public:
Foo foo;
Bar bar;
Baz() {
std::cout << "In Baz::Baz()" << std::endl;
}
Baz(const Baz& rhs) {
std::cout << "In Baz::Baz(const Baz&)" << std::endl;
}
};
int main() {
Baz baz1;
std::cout << "Copying..." << std::endl;
Baz baz2(baz1);
}
как есть, это печатает:
In Foo::Foo()
In Bar::Bar()
In Baz::Baz()
Copying...
In Foo::Foo()
In Bar::Bar()
In Baz::Baz(const Baz&)
Обратите внимание, что это по умолчанию инициализации членам Baz
.
закомментировав явный конструктор копирования, как:
/*
Baz(const Baz& rhs) {
std::cout << "In Baz::Baz(const Baz&)" << std::endl;
}
*/
Выход будет так:
In Foo::Foo()
In Bar::Bar()
In Baz::Baz()
Copying...
In Foo::Foo(const Foo&)
In Bar::Bar(const Bar&)
Он называет копию-конструктор на обоих.
И если мы вновь Baz
конструктор копирования и явно скопировать один элемент:
Baz(const Baz& rhs) :
foo(rhs.foo)
{
std::cout << "In Baz::Baz(const Baz&)" << std::endl;
}
Получаем:
In Foo::Foo()
In Bar::Bar()
In Baz::Baz()
Copying...
In Foo::Foo(const Foo&)
In Bar::Bar()
In Baz::Baz(const Baz&)
Как вы можете видеть, как только вы явно объявить копию-конструктор вы отвечаете за копирование всех членов класса; это ваш конструктор.
Это относится ко всем конструкторам, включая конструкторы перемещения.
См. Http://stackoverflow.com/questions/563221/is-there-an-implicit-default-constructor-in-c/563320#563320 –