如果不考虑返回值优化,bts 对于给定代码来说是这样工作的吗?

问题描述 投票:0回答:1
#include<bits/stdc++.h>

using namespace std;

class A{
    
    public:
    int data;
    A(int s){
       data=s; 
    }
    
    A(A &obj){
        data=obj.data;
        cout<<"Copy"<<endl;
    }
};


A getobject(){
    A obj(2);
    return obj;
}

int main(){
    
    
    A newobj = getobject();
    
    return 0;
}

我的理解是,首先创建临时对象来存储 getobject() 函数返回的对象,然后将临时对象复制到 newobj 中,从而调用复制构造函数。如果这是真的,那么是否就像我们将返回的 obj 存储到临时对象中时一样,也使用了复制机制,如果不是,那么会怎样?

注意-请忽略命名空间和库。

c++ constructor c++17 return-value-optimization
1个回答
0
投票

我的理解是,首先创建临时对象来存储 getobject() 函数返回的对象,然后将临时对象复制到 newobj 中,从而调用复制构造函数。如果这是真的,那么是否就像我们将返回的 obj 存储到临时对象中时一样,也使用了复制机制,如果不是,那么会怎样?

自 C++17 起,这些都不是真的。从根本上来说,代码中只有两个对象:从变量

obj
实例化的对象和从变量
newobj
实例化的对象。即使原则上也不存在临时对象。

getobject()
是一个纯右值表达式,它立即初始化其结果对象,它与函数返回值中的表达式是
newobj
,即
newobj
是从表达式
obj
复制初始化的,除了有一个特殊的当
return
语句中的表达式仅命名局部变量时,遵循此规则。在这种情况下,
obj
被认为是xvalue(即右值)而不是通常的左值,因此将使用移动构造函数而不是复制构造函数。 (从技术上讲,最后一句话仅在 C++23 后才成立,之前它更复杂,但这里的结果相同。)

从函数返回时不再进行返回值优化或复制省略,尽管 C++17 规则被随意称为“强制复制省略”。唯一仍然可能的复制省略是命名的返回值优化,它将

obj
newobj
一起识别,以便总共只有一个没有任何副本或移动的对象存在。

© www.soinside.com 2019 - 2024. All rights reserved.