对于一个类,默认初始化和复制初始化到值初始化纯右值有什么区别?

问题描述 投票:0回答:4

这有什么区别:

TestClass t;

还有这个:

TestClass t = TestClass();

我预计第二个可能会调用构造函数两次,然后调用operator=,但它只调用构造函数一次,就像第一个一样。

c++ constructor initialization default-constructor copy-assignment
4个回答
16
投票
TestClass t;

调用默认构造函数。

TestClass t = TestClass();

是一个复制初始化。它将调用

TestClass()
的默认构造函数,然后调用复制构造函数(理论上,复制会受到 copy elision 的影响)。 此处不进行任何分配

还有直接初始化的概念:

TestClass t(TestClass());

如果你想使用赋值运算符:

TestClass t;
TestClass s;
t = s;

4
投票

第一种情况非常简单 - 使用默认构造函数构造一个实例。

第二类是构造匿名对象,然后调用复制构造函数。请注意,这里的

=
不是赋值,它类似于(但不相同)写作:

TestClass t(TestClass());

我们可以通过使其不可用来验证这是否需要复制构造函数可用,例如:

#include <iostream>

struct TestClass {
  TestClass() { std::cout << "Ctor" << std::endl; }
  TestClass(const TestClass&)  = delete;
};

int main() {
  TestClass t = TestClass();
}

由于删除了复制构造函数而无法编译。 (在 C++03 中,您可以使用

private:
代替)。

实际上最有可能发生的情况是,您的编译器正在执行返回值优化,从而允许完全省略对复制构造函数的调用提供存在合适的复制构造函数并且可以访问。


1
投票

在第一个中,您正在隐式调用默认构造函数。在第二个中,你明确地称它为


1
投票
后一个

可以调用复制构造函数,因此需要一个是公共的。

编辑:我确实从您使用的类型名称中得出了太大的结论。上面的句子仅适用于类类型(即不适用于 POD)。对于 POD 类型,前者使变量未初始化,而后者使用所谓的“默认”值对其进行初始化。

© www.soinside.com 2019 - 2024. All rights reserved.