Foo f1;
Foo f2(f1);
是的,这段代码会实现你所期望的功能:
Foo 的 f2 拷贝构造函数 Foo::Foo(Foo const&) 会被调用。
该拷贝构造函数会递归地对其基类和每个成员进行拷贝构造。
如果你定义了一个如下的类:
class X: public Y
{
private:
int m_a;
char* m_b;
Z m_c;
};
以下方法将由您的编译器定义。
- 构造函数(默认)(2个版本)
- 构造函数(复制)
- 析构函数(默认)
- 赋值运算符
构造函数:默认:
实际上有两个默认构造函数。
其中一个用于“零初始化”,而另一个用于“值初始化”。使用哪个取决于您在初始化期间是否使用了()
。
X::X()
:Y()
,m_a(0)
,m_b(0)
m_c()
{
}
X::X()
:Y()
m_c()
{
}
注意:如果基类或任何成员没有有效的可见默认构造函数,则无法生成默认构造函数。除非您的代码尝试使用默认构造函数(然后只有编译时错误),否则这不是一个错误。
构造函数(拷贝)
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);
m_a = copy.m_a;
m_b = copy.m_b;
m_c = copy.m_c;
return *this;
}
注意:如果基类或任何成员没有有效的可行赋值运算符,那么赋值运算符将无法生成。除非代码尝试使用赋值运算符(这时只会出现编译时错误),否则这不是一个错误。
析构函数
X::~X()
{
}
m_c.~Z();
~Y();
- 如果声明任何构造函数(包括复制构造函数),则编译器不会实现默认构造函数。
- 如果声明了复制构造函数,则编译器不会生成一个。
- 如果声明了赋值运算符,那么编译器将不会生成一个。
- 如果声明了析构函数,那么编译器将不会生成一个。
查看您的代码后,以下复制构造函数会被生成:
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)
{}
m_a
、m_b
和m_c
不是非常具有信息量的名称。这本来不是问题,但你最初将它们定义为m_a
、m_c
(对于char*
),以及m_d
(对于Z
类型)。我猜更具有信息量的名称可以避免这个小错误。无论如何,因为你的好帖子还是给你点赞。 - Chris Lutz