12

这有什么区别:

TestClass t;

和这个:

TestClass t = TestClass();

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

4

4 回答 4

16
TestClass t;

调用默认构造函数。

TestClass t = TestClass();

拷贝初始化。它将调用默认构造函数TestClass(),然后调用复制构造函数(理论上,复制受复制省略的影响)。这里没有分配

还有直接初始化的概念:

TestClass t(TestClass());

如果要使用赋值运算符:

TestClass t;
TestClass s;
t = s;
于 2012-08-07T20:38:35.623 回答
4

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

第二个类是构造一个匿名对象,然后调用复制构造函数。请注意,这里的=is 不是赋值,它类似于(但不相同)写作:

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:改用)。

但实际上最有可能发生的是您的编译器正在执行Return value optimization,从而允许它完全省略对复制构造函数的调用,前提是存在合适的构造函数并且可以访问。

于 2012-08-07T20:41:57.980 回答
2

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

于 2012-08-07T20:42:15.017 回答
1

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

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

于 2012-08-07T20:36:45.443 回答