我知道如果你将一个成员从no-arg构造函数中的一个初始化列表中删除,那么将调用该成员的默认构造函数.
复制构造函数同样调用成员的复制构造函数,还是也调用默认构造函数?
class myClass { private: someClass a; someOtherClass b; public: myClass() : a(DEFAULT_A) {} //implied is b() myClass(const myClass& mc) : a(mc.a) {} //implied is b(mc.b)??? or is it b()? }
GManNickG.. 26
显式定义的复制构造函数不会为成员调用复制构造函数.
当您输入构造函数的主体时,将初始化该类的每个成员.也就是说,一旦你到达,{
你就可以保证你的所有成员都已经初始化了.
除非指定,否则成员将按其在类中出现的顺序进行默认初始化.(如果它们不可能,程序就会形成错误.)因此,如果您定义自己的复制构造函数,现在可以根据需要调用任何成员复制构造函数.
这是一个小程序,你可以复制粘贴到某个地方并乱用:
#includeclass 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&)
它在两者上调用copy-constructor.
如果我们重新引入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&)
如您所见,一旦您明确声明了一个复制构造函数,您就要负责复制所有类成员; 它现在是你的构造函数.
这适用于所有构造函数,包括移动构造函数.
显式定义的复制构造函数不会为成员调用复制构造函数.
当您输入构造函数的主体时,将初始化该类的每个成员.也就是说,一旦你到达,{
你就可以保证你的所有成员都已经初始化了.
除非指定,否则成员将按其在类中出现的顺序进行默认初始化.(如果它们不可能,程序就会形成错误.)因此,如果您定义自己的复制构造函数,现在可以根据需要调用任何成员复制构造函数.
这是一个小程序,你可以复制粘贴到某个地方并乱用:
#includeclass 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&)
它在两者上调用copy-constructor.
如果我们重新引入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&)
如您所见,一旦您明确声明了一个复制构造函数,您就要负责复制所有类成员; 它现在是你的构造函数.
这适用于所有构造函数,包括移动构造函数.