C++:如果没有对这些不同的创建/初始化、复制、分配方式进行优化,输出是什么?

C++: What is the output, if no optimizations are applied to these different ways to create/initialize, copy, assign?

提问人:pasha 提问时间:8/13/2021 最后编辑:pasha 更新时间:8/16/2021 访问量:106

问:

我发现变量的构造、复制、分配方式有些混乱,因为在我尝试的编译器中,它们通常会应用某种优化(删除临时等)。

我在下面的评论中列出了我尝试过的不同方法和程序的输出。可能其中一些包括临时对象创建,但被编译器优化了?请说明输出是否符合标准,以及如果不应用优化,输出是什么。

#include <iostream>
using namespace std;

class type {
    public:
    type(int z){cout << "ctor"<<endl;};
    type(const type&){cout<<"copy"<<endl;}
    void operator=(const type& ){cout <<"assign"<<endl;}
};
int main()
{
//constructor
type c(8);         //ctor 
type c2{8};        //ctor 
type c3 = 8;       //ctor  
type c4 = {8};     //ctor
type c5 = type(8); //ctor
type c6 = type{8}; //ctor
cout <<endl; 

//copy 
type ci0(c);        //copy
type ci1{c};        //copy
type ci2 = c;       //copy
type ci3 = {c};     //copy
type ci4 = type(c); //copy
type ci5 = type{c}; //copy
cout <<endl;

//assign
c2 = c;        //assign
c2 = {c};      //assign
c2 = type{c};  //copy and then assign
c2 = type(c);  //copy and then assign
c2 = 8;        //ctor and then assign
c2 = {8};      //ctor and then assign
c2 = type(8);  //ctor and then assign
c2 = type{8};  //ctor and then assign
}
C++ C++11 构造函数 copy-constructor copy-assignment

评论

1赞 Ruks 8/13/2021
您还可以使用以下命令创建对象的副本: 和 。type ci4 = {c}type ci5 = type{c}type ci6 = type(c)
0赞 Joe 8/13/2021
你标记的大部分内容 copy 都不是 copy,而只是构造函数。你电缆上的一些内容在技术上是ctor,然后是分配。但是编译器 i
0赞 sweenish 8/13/2021
@Joe 标记的所有 3 行都会调用复制构造函数,那么你想说什么?copy
2赞 cigien 8/13/2021
请试着把问题重点放在更多地方。您询问的是一组非常大且包含许多特殊情况的功能。以目前的形式,我认为这个问题不合适。有没有你不清楚的具体情况?
0赞 Joe 8/13/2021
对不起,我的评论在我完成之前就无意中发布了。我建议仔细阅读 l 值和 r 值之间的区别。如今,识别 r 值的编译器可以优化过去的构造,然后将其赋值为简单的构造

答:

0赞 pasha 8/16/2021 #1

使用显式 to ctor 和复制 ctor 并删除每个函数,我能够得到以下结果。

//constructor
type c(8);         //explicit ctor 
type c2{8};        //explicit ctor 
type c3 = 8;       //implicit ctor, explicit copy  
type c4 = {8};     //implicit ctor
type c5 = type(8); //explicit ctor, implicit copy
type c6 = type{8}; //explicit ctor, implicit copy
cout <<endl; 

//copy 
type ci0(c);        //explicit copy
type ci1{c};        //explicit copy
type ci2 = c;       //implicit copy
type ci3 = {c};     //implicit copy
type ci4 = type(c); //implicit copy
type ci5 = type{c}; //implicit copy
cout <<endl;

//assign
c2 = c;        //assign
c2 = {c};      //assign
c2 = type{c};  //implicit copy and then assign
c2 = type(c);  //implicit copy and then assign
c2 = 8;        //implicit ctor and then assign
c2 = {8};      //implicit ctor and then assign
c2 = type(8);  //explicit ctor and then assign
c2 = type{8};  //explicit ctor and then assign