5

A a1(5); 之间有什么区别?和 A a2 = A(5) ?这两个作品,但我真的很想知道它们之间的区别,因为我在我的一个项目中使用了方法 2,并且在我更改为方法 1 后我遇到了一个错误。提前致谢!

class A {
public:
    int val;
    A() : val(0) {}
    A(int newVal) : val(newVal) {}
};

int main()
{
    A a1(5);  // method 1
    A a2 = A(5); // method 2
}
4

2 回答 2

8
A a1(5);  // method 1
A a2 = A(5); // method 2

第一个称为直接初始化,第二个称为复制初始化。

如果您使复制构造函数不可访问或/并且未将其定义为,则第二个将不会编译:

class A {
public:
    int val;
    A() : val(0) {}
    A(int newVal) : val(newVal) {}
private:
    A(A const&);  //the second one will not compile
};

现在第二个将无法编译。请注意,它不会在这两种情况下编译:

  • 如果复制构造函数已定义,但不可访问(它是privateprotected)。
  • 如果声明了复制构造函数,但未定义。
于 2012-06-22T04:24:32.143 回答
1

严格来说,阅读您的问题,我希望您提供这两个示例

A a1(5);  // method 1
A a2 = 5; // method 2

第一个是直接初始化。第二个是复制初始化。

在问题中提供的示例实际上已经说明了两者之间的区别:)

直接初始化直接初始化目标对象,作为一个单步过程,通过查找和使用适当的构造函数。复制初始化在概念上是一个两步过程:首先它A通过一些转换构造函数构造一个临时类型的对象,然后使用复制构造函数将其复制到目标对象。IE

A a2 = 5;

实际上会起作用

A a2 = A(5);

这实际上详尽地解释了差异。

第二个变体的两步结构同样是概念性的。编译器被允许(并将)优化第二个变体,使其与第一个变体完全相同。它们将消除中间临时对象并直接执行初始化。

于 2012-06-22T04:26:22.443 回答