0

为什么这段代码无法编译?如果我将复制构造函数访问级别更改为公共,就可以并打印“Foo::Foo(int)”。如果我写“Foo instance(0);” 而不是“Foo instance = 0;” 它也会好的。为什么?这种行为的意义何在?

#include <iostream>

struct Foo
{
public:
   int i;
   Foo(int i) : i(i) { std::cout << "Foo::Foo(int) \n"; }

private:
   Foo(const Foo&) { std::cout << "Foo::Foo(const Foo&) \n"; }
};

int main()
{
   Foo instance = 0;
}
4

2 回答 2

2

Foo instance = 0;使用复制初始化。使用非显式构造函数将其转换为对象,0然后将其复制到 make 。它相当于:FooFoo(int i)instance

Foo instance = Foo(0);

这需要您将其设为私有的复制构造函数。

当您将其公开时,转换构造函数打印但复制构造函数不打印的原因是因为编译器可以省略副本以进行优化。这是一种可能会改变代码执行的优化形式。然而,复制构造函数仍然需要是公共的,无论它是否被省略。换句话说,副本需要在被删除之前成为可能。

如果您进行转换构造函数explicit,它将无法编译:

explicit Foo(int i) : i(i) { std::cout << "Foo::Foo(int) \n"; }
于 2012-11-26T20:41:44.180 回答
1

因为

Foo instance = 0;

复制初始化,需要一个可访问的复制构造函数。它尝试使用转换构造函数从临时创建一个Foo0然后使用复制构造函数instance从临时创建。Foo

相比之下,

Foo instance(0);

直接初始化,只需要转换构造函数。

相关:复制和直接初始化行为不同的背后动机是什么?

于 2012-11-26T20:39:20.500 回答