C++ & 符号和从函数接收对象
C++ ampersand receiving object from function
我有以下简单的代码,其中包含一个普通构造函数和一个复制构造函数的类
class largeObj
{
public:
largeObj()
{
printf("nNormal constructorn");
}
largeObj(const largeObj& mv)
{
printf("nCopy constructorn");
}
~largeObj()
{
printf("nDestroying..n");
}
void tryme()
{
printf("nHi :)n");
}
};
largeObj iReturnLargeObjects()
{
largeObj md;
return md;
}
int main()
{
largeObj mdd = iReturnLargeObjects();
mdd.tryme();
return 0;
}
输出为
普通构造函数
复制构造函数
破坏。。
嗨:)
我明白了原因。
但是如果我替换以下行
largeObj mdd = iReturnLargeObjects();
跟
largeObj& mdd = iReturnLargeObjects();
输出是一样的,这是为什么?
我的意思是:在第一种情况下不应该有另一个副本(没有 &)吗?这两行之间有什么区别,为什么它们的行为相同?
largeObj& mdd = iReturnLargeObjects();
不能将可变左值引用绑定到右值。这是非法的C++,只有某些特定的编译器扩展才允许。然而,问题的语义是没有改变的,即使这一提法是const
的,因此转让是合法的。
输出没有什么不同的原因是因为称为 RVO 的编译器优化。这种优化在C++标准中是明确允许的,它允许编译器在某些限制内跳过构造它认为不必要的对象 - 即使这样做会改变程序的语义,这使其成为非常不寻常的优化。
底线是:不要在复制/移动构造函数和析构函数中放置副作用,因为编译器可以消除它们,即使程序的正确性取决于调用它们。
你用的是什么编译器,我敢打赌这是有效的,因为你使用的任何编译器都不会在返回后将未使用的堆栈变量清零,你没有得到 seg 错误,因为它仍然是你的堆栈。 基本上MD被留在堆栈上,从技术上讲,您仍然可以解决。 两者之间的区别是
大Obj md;
是一个接收整个变量的变量。
largeObj& mdd = iReturnLargeObjects();
是对由于惰性编译器仍然存在的变量的引用。
相关文章:
- 如何创建对象函数指针C++映射?
- 为什么我可以改变常量对象中的成员变量,这是返回常量对象函数的结果?
- 如何将对象函数的实例传递给另一个函数
- 调用模板函数的问题"No matching function for call"参数:迭代器、对象函数
- makefile对我的名称空间对象/函数/构造函数的不确定引用
- 将对象函数转换为函数指针
- 非对象函数/类函数C++
- 线程对象函数 C++
- C 将成员对象函数分配给类成员功能
- 使用基本指针调用派生对象函数
- 可以(通过编译器)使用多少个线程来初始化全局对象(函数main之前)
- C++类对象函数
- 对对象::函数的未定义引用
- 无法弄清楚将多个对象函数作为单独的线程调用的语法
- 在提升作用域出口中调用对象函数
- 使用基指针来使用派生对象函数
- 在for_each lambda 中调用对象函数
- C++:: 模板函数 - 从对象函数获取对象的地址
- Qt5 未解析的外部静态元对象函数
- 通过变量使用对象和对象函数