每次调用一个默认构造函数时调用构造函数?
当我遇到这个问题时,我正在浏览构造函数初始化列表中的一些问题。
考虑这个:
class Student {
public:
Student() {
id = 0;
}
Student(int i) {
id = i;
}
private:
int id;
};
现在,检查一下:
当你进入构造函数的主体时,所有的字段都已经被构造了; 如果他们有默认的构造函数,那些已经被调用。 现在,如果您在构造函数的主体中为它们赋值,那么您正在调用复制构造函数。 这是低效的,因为两个构造函数最终被调用而不是一个。
来源:C ++构造函数名称后面的冒号是做什么的?
那么,这是否意味着当我调用无参构造函数时,复制构造函数也被调用?
请解释。 这真是令人困惑。
特别是第一行的含义:
当你进入构造函数的主体时,所有的字段都已经被构建
这意味着int id
在你到达id = 0
之前已经被初始化了。 由于没有指定明确的初始化程序,因此它已被默认初始化。 另外,因为它是一个int
,初始化规则告诉使用它将有一些不确定的值。
在实践中,对于int
或任何初始化非常便宜的类型,这并不重要。
如果不是使用int
成员,而是使用一个类,我们可以更清楚地看到幕后实际发生了什么:
#include <iostream>
class Verbose {
public:
Verbose() {
std::cout << __PRETTY_FUNCTION__ << "n";
}
Verbose(int) {
std::cout << __PRETTY_FUNCTION__ << "n";
}
Verbose(Verbose const &) {
std::cout << __PRETTY_FUNCTION__ << "n";
}
Verbose & operator=(Verbose const &) {
std::cout << __PRETTY_FUNCTION__ << "n";
return *this;
}
~Verbose() {
std::cout << __PRETTY_FUNCTION__ << "n";
}
};
class Object {
public:
Verbose v;
Object() {
v = Verbose(3);
}
};
int main() {
Object o;
}
此代码将输出:
Verbose::Verbose()
Verbose::Verbose(int)
Verbose &Verbose::operator=(const Verbose &)
Verbose::~Verbose()
Verbose::~Verbose()
请注意,我们:
v
。 Verbose(3)
Object o
超出作用域时,我们将销毁成员变量。 请注意,我们基本上构建了两次Verbose v
! 我们首先使用了默认的构造函数,然后我们基本上使用operator=
call来重建它。 如果我们使用初始化器列表,我们可以将其减少到一个调用Verbose(int)
。
他们是这个意思
Student() {
id = 0;
}
效率低于
Student() : id(0) {}
在这个特定的例子中,由于成员只是一个int
,所以id
将在一个步骤中被初始化。
相反,如果Student
有更复杂的成员,如Backpack
和Books
,则后一种方法会有所不同。 如果这些类不是POD,则第一种方法需要两步才能初始化成员,第二种方法只需要一步即可初始化。
上一篇: Copy constructor called everytime a default constructor is called?
下一篇: Rule of Three in C++