两种初始化之间有什么区别:Foo f(); Foo f = Foo()

时间:2018-06-26 05:52:12

标签: c++

class Foo
{
public:
    Foo(){}
private:
    Foo(const Foo &);
};

Foo f();
Foo f1 = Foo();

我发现当我将Foo(const Foo &)声明为私有时,Foo f1 = Foo();无法编译。因此我认为Foo f1 = Foo();只需调用复制构造函数,但是当我将代码更改为:

class Foo
{
public:
    Foo(){}
    Foo(const Foo &){std::cout<<"Foo(const Foo &)";}

};

Foo f();
Foo f1 = Foo();

它什么都不会打印。所以两次初始化Foo f(); Foo f = Foo()有什么区别?

2 个答案:

答案 0 :(得分:5)

由于copy elision,不必调用复制构造函数。复制构造函数仍然必须作为公共成员存在。

然后Foo f();声明一个名为f函数,不接受任何参数,并按值返回一个Foo对象。

答案 1 :(得分:1)

要正式回答实际问题,代码

Foo f1 = Foo();

使用默认构造函数创建类型为Foo的临时对象,并使用复制构造函数将f1构造为该临时对象的副本,然后销毁该临时对象。

Foo f;

使用默认构造函数创建f

使用复制构造函数进行的小动作并不是听起来那么低效。早在过去,只要可以访问复制构造函数,就可以允许编译器跳过临时副本,并直接初始化f1。这称为“复制删除”。结果代码与Foo f1;相同。但是,如果Foo没有复制构造函数,或者在初始化时无法访问该构造函数(例如,复制构造函数是私有的,并且初始化未在成员函数内部完成),则代码无效。

然后必须取消复制:编译器不再只是允许跳过临时程序; 必需

现在,显然,甚至不再需要复制构造函数存在并且可以访问;编译器需要将第一种形式转换为第二种形式,因此两者相同