为什么编译器在这种情况下没有省略副本构造
why compiler is not eliding away copy construction in this case
class test
{
public:
int data;
test(int var = 0):data(var){cout<<"constructor"<<endl;}
~test(){ cout<<"destructor"<<endl; }
test(const test& var)
{
cout<<"copy constructor"<<endl;
this->data = var.data;
}
test& operator=( const test& var)
{
cout<<"assignment op"<<endl;
this->data = var.data;
return *this;
}
};
test passByref_returnByVal(test& obj)
{
return obj;
}
int main()
{
test o1(5);
test o2 = passByref_returnByVal(o1);
cout<<"=========================="<<endl;
test o3;
o3 = passByref_returnByVal(o1);
}
输出:
constructor
copy constructor
constructor
copy constructor
assignment op
destructor
在给定的示例中,对象o2
是直接复制构造的,而不使用任何临时变量。
但是在第二种情况下,我希望o3
被分配函数的返回值,首先使用复制构造函数创建一个临时值,然后调用赋值运算符进行值赋值。
我的问题是,当我的分配操作员参考时,这个临时需要什么。我找到了相关的问题,但他们没有回答这个问题。
test o3;
将导致调用构造函数来创建对象。 C++不是 Java,其中对象类型声明仅声明引用但不实例化对象。
test passByref_returnByVal(test& obj) {....}
导致复制构造函数调用,因为当您在其中执行return obj;
编译器需要创建一个临时对象,因为该函数的返回类型是test
(而不是test&
或test*
)。
最后,因为o3
已经存在了
test o3;
声明,调用赋值运算符以将 passByref_returnByVal
的返回值分配给已经存在的o3
。
所以复制构造函数调用发生在passByref_returnByVal
,而不是在你的operator=
中。
相关文章:
- C/C++编译器通常会删除重复的库吗
- 模板-模板参数推导:三个不同的编译器三种不同的行为
- Win32编译器选项和内存分配
- MSVC多行宏编译器错误
- 静态数据成员的问题-修复链接错误会导致编译器错误
- C++,我收到一个无法理解的编译器错误
- 在线编译器中的分段C++没有打印消息
- 如何解决gcc编译器优化导致的centos双编译器设置中的分段错误
- C/C++预处理器是否可以检测一些编译器选项
- 是否有C++编译器选项允许激进地删除所有函数调用,并将参数传递给具有空体的函数
- 当类型适当的构造函数可用时,为什么一个编译器尝试使用已删除的副本构造函数
- 诱导编译器避免/触发副本
- 是否可以指示编译器省略C++中返回的variant_t的副本
- 为什么编译器在这种情况下没有省略副本构造
- C++我可以期望所有编译器都不会销毁返回的副本
- 编译器副本构造的优化
- 任何编译器真的会删除这些副本吗
- C++编译器'shallow'副本和赋值
- 在编译器生成的副本构造函数之上强制使用模板化构造函数
- 编译器可以删除以下副本吗