C++ 两个初始化之间的区别是什么:Foo f();Foo f=Foo()
我发现当我向private声明C++ 两个初始化之间的区别是什么:Foo f();Foo f=Foo(),c++,C++,我发现当我向private声明Foo(constfoo&)时,foof1=Foo()不编译。所以我认为Foo f1=Foo();只需调用复制构造函数,但当我将代码更改为: class Foo { public: Foo(){} private: Foo(const Foo &); }; Foo f(); Foo f1 = Foo(); class-Foo { 公众: Foo(){} Foo(const Foo&){std::cout,因为不必调用复制构造函数。但复制构
Foo(constfoo&)
时,foof1=Foo()代码>不编译。所以我认为Foo f1=Foo()
;只需调用复制构造函数,但当我将代码更改为:
class Foo
{
public:
Foo(){}
private:
Foo(const Foo &);
};
Foo f();
Foo f1 = Foo();
class-Foo
{
公众:
Foo(){}
Foo(const Foo&){std::cout,因为不必调用复制构造函数。但复制构造函数必须仍然作为公共成员存在
和Foo f();
声明一个名为f
的函数,不带任何参数,并按值返回Foo
对象。由于不必调用复制构造函数,因此复制构造函数必须仍然作为公共成员存在
和Foo f();
声明一个名为f
的函数,不带任何参数,并按值返回Foo
对象。为了回答实际问题,正式地说,代码
class Foo
{
public:
Foo(){}
Foo(const Foo &){std::cout<<"Foo(const Foo &)";}
};
Foo f();
Foo f1 = Foo();
使用默认构造函数创建类型为Foo
的临时对象,并使用复制构造函数将f1
构造为该临时对象的副本,然后销毁该临时对象
Foo f1 = Foo();
使用默认构造函数创建f
与复制构造函数的这种小小的舞蹈并不像听起来那么低效。在过去,只要可以访问复制构造函数,编译器就可以跳过临时的,直接初始化f1
。这被称为“复制省略”。生成的代码与Foo f1;
相同。但是,如果Foo
没有副本构造函数,或者在初始化时无法访问该构造函数(例如,副本构造函数是私有的,初始化未在成员函数内完成),则该代码无效
然后,复制省略变成了强制性的:编译器不再只允许跳过临时的;它是必需的
现在,显然,甚至不再要求复制构造函数存在并且可以访问;编译器需要将第一种形式转换为第二种形式,因此这两种形式是相同的,以回答实际问题,正式地说,代码
class Foo
{
public:
Foo(){}
Foo(const Foo &){std::cout<<"Foo(const Foo &)";}
};
Foo f();
Foo f1 = Foo();
使用默认构造函数创建类型为Foo
的临时对象,并使用复制构造函数将f1
构造为该临时对象的副本,然后销毁该临时对象
Foo f1 = Foo();
使用默认构造函数创建f
与复制构造函数的这种小小的舞蹈并不像听起来那么低效。在过去,只要可以访问复制构造函数,编译器就可以跳过临时的,直接初始化f1
。这被称为“复制省略”。生成的代码与Foo f1;
相同。但是,如果Foo
没有副本构造函数,或者在初始化时无法访问该构造函数(例如,副本构造函数是私有的,初始化未在成员函数内完成),则该代码无效
然后,复制省略变成了强制性的:编译器不再只允许跳过临时的;它是必需的
现在,显然,甚至不再要求复制构造函数存在并且可以访问;编译器需要将第一种形式转换为第二种形式,因此在C++17中,这两种形式是相同的,因此不再需要复制构造函数。在C++17之前,复制构造函数在C++17中不能是显式的++17复制构造函数不再是必需的。在C++17之前,复制构造函数不能是显式的。区别在于第一个不是初始化。它是一个函数声明,就像int f()但这不是真正的问题。区别在于第一个不是初始化。它是一个函数声明,就像int f();
。但这不是真正的问题。