包含其他对象的类的C ++隐式复制构造函数 [英] C++ implicit copy constructor for a class that contains other objects
问题描述
我知道编译器有时提供一个默认的复制构造函数,如果你不实现自己。我很困惑这个构造函数究竟是什么。如果我有一个类包含其他对象,没有一个声明的复制构造函数,行为是什么?例如,这样的类:
I know that the compiler sometimes provides a default copy constructor if you don't implement yourself. I am confused about what exactly this constructor does. If I have a class that contains other objects, none of which have a declared copy constructor, what will the behavior be? For example, a class like this:
class Foo {
Bar bar;
};
class Bar {
int i;
Baz baz;
};
class Baz {
int j;
};
现在,如果我这样做:
Foo f1;
Foo f2(f1);
默认的拷贝构造函数会做什么?将 Foo
中的编译器生成的复制构造函数调用 Bar
中的编译器生成的构造函数以复制 bar
,然后调用 Baz
?
What will the default copy constructor do? Will the compiler-generated copy constructor in Foo
call the compiler-generated constructor in Bar
to copy over bar
, which will then call the compiler-generated copy constructor in Baz
?
推荐答案
Foo f1;
Foo f2(f1);
是的,这将是您期望的:
f2复制构造函数调用了Foo :: Foo(Foo const&)。
此副本构造其基类,然后构造其每个成员(递归)
Yes this will do what you expect it to:
The f2 copy constructor Foo::Foo(Foo const&) is called.
This copy constructs its base class and then each member (recursively)
这样的类:
class X: public Y
{
private:
int m_a;
char* m_b;
Z m_c;
};
以下方法将由您的编译器定义。
The following methods will be defined by your compiler.
- 构造函数(默认)(2个版本)
- 构造函数(复制)
- / li>
- 分配运算符
实际上有两个默认构造函数。
一个用于零初始化
,而另一个用于值初始化
。使用取决于在初始化期间是否使用()
。
There are actually two default constructors.
One is used for zero-initialization
while the other is used for value-initialization
. The used depends on whether you use ()
during initialization or not.
// 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'
{
}
注意:如果基类或任何成员没有有效的可见默认构造函数,不能生成。这不是一个错误,除非你的代码试图使用默认的构造函数(只有编译时错误)。
Notes: If the base class or any members do not have a valid visible default constructor then the default constructor can not be generated. This is not an error unless your code tries to use the default constructor (then only a compile time error).
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)
{}
注意:如果基类或任何成员没有有效的可见拷贝构造函数,那么无法生成拷贝构造函数。这不是一个错误,除非你的代码试图使用复制构造函数(只有编译时错误)。
Notes: If the base class or any members do not have a valid visible copy constructor then the copy constructor can not be generated. This is not an error unless your code tries to use the copy constructor (then only a compile time error).
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;
}
注意:如果基类或任何成员没有有效的可行赋值运算符,则不能生成赋值运算符。这不是一个错误,除非你的代码试图使用赋值运算符(然后只有编译时错误)。
Notes: If the base class or any members do not have a valid viable assignment operator then the assignment operator can not be generated. This is not an error unless your code tries to use the assignment operator (then only a compile time error).
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
- 如果声明了复制构造函数,那么编译器将不会生成一个。 $> b $ b
- 如果赋值运算符被声明,编译器将不会生成一个。
- 如果声明了析构函数,编译器不会生成一个。
- If any constructor (including copy) is declared then the default constructor is not implemented by the compiler.
- If the copy constructor is declared then the compiler will not generate one.
- If the assignment operator is declared then the compiler will not generate one.
- If a destructor is declared the compiler will not generate one.
查看您的代码,生成以下副本构造函数:
Looking at your code the following copy constructors are generated:
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)
{}
这篇关于包含其他对象的类的C ++隐式复制构造函数的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!