C++返回本地对象
C++ return local object
我和几位同事正在讨论当从C++方法返回局部变量(分配在堆栈上)时会发生什么。
以下代码适用于单元测试,但我相信这只是因为单元测试很幸运,并且没有尝试重用obj.使用的堆栈上的内存
这样行吗
static MyObject createMyObject() {
MyObject obj;
return obj;
}
发生的情况是,复制构造函数被调用以生成本地对象的副本,而这正是调用者接收到的。
编译器可能会在一个称为副本省略的过程中消除副本,但这取决于编译器——你对它没有太多控制权
这种模式能够产生您担心的问题,但前提是您将指针或引用返回到本地对象。
obj
,然后使用对象的复制构造函数将其从方法/函数中复制出来。
您也可以通过声明该static
来使该obj
不在堆栈中。返回对象也会返回一个副本,但并不是每次调用函数时都会创建对象。然后,您可以返回对象作为参考:
static MyObject & createMyObject() {
static MyObject obj;
return obj;
}
(此处没有副本,而且obj
只创建一次,并且其地址在运行时保持不变)。
您按值返回对象,因此它的复制构造函数将被调用,原始对象的copy将被返回并存储在调用方的堆栈上。如果此方法返回局部变量的指针(或引用),它将失败。
返回MyObject的副本。如果MyObject有一个可以正确复制所有内容的复制构造函数,这应该是可以的。请注意,它可能有一个复制构造函数,即使没有明确列出一个——编译器定义的默认复制构造函数(按成员分配所有内容)可能对您的目的很好。
在本例中,MyObject是按值返回的。这意味着它将被复制并传递回调用函数。(在某些情况下,编译器可以优化伪造的副本,但只有当这相当于在MyObject上调用副本构造函数并将副本放在堆栈上时。)
假设其他人只是错过了这个问题中一个明显的困惑来源——static
:
您并没有将在中创建并从createMyObject
返回的MyObject
实例声明为具有静态存储持续时间;相反,您将函数createMyObject
声明为具有内部链接。
函数可以"返回本地对象";,因为编译器会将函数转换为,而不是真正返回值。相反,它将接受引用MyObject& __result
,并使用将被分配返回值的本地对象(即obj
)来复制构造__result
。在您的情况下,函数将被重写为:
static void createMyObject(MyObject& __result) {
MyObject obj;
// .. process obj
// compiler generated invocation of copy constructor
__result.MyObject::Myobject( obj );
return;
}
并且CCD_ 12的每次调用也将被转换以将引用绑定到现有对象。例如,调用以下表单:
MyObject a = createMyObject();
将转换为:
MyObject a; // no default constructor called here
createMyObject(a);
但是,如果返回指向本地对象的引用或指针,编译器将无法完成转换。您将返回一个指向已销毁对象的引用或指针。
这很好用。它将创建一个临时匿名变量,返回MyObject:
匿名变量和对象
将临时对象绑定到对const 的引用
- 如何通过另一个对象中的命令正确地从一个对象返回数据
- 如何访问从 COM 对象返回的 VARIANT 数据类型中的安全数组C++?
- 从我的对象返回静态数组
- 将unique_ptr作为<Object>unique_ptr<常量对象返回>
- 从右值对象返回成员
- 视觉对象 返回 C++ 中的双精度值
- 为什么类型为 sf::Text 的对象返回不同的 getPosition().y 和 getLocalBounds().
- std::min_element 从类对象返回意外结果
- C++无效的对象返回语义
- const引用是否延长临时对象返回的临时对象的寿命
- 将 NULL 作为对象返回时未收到任何警告
- 如何在 C# 中从 com 对象返回数组(double[])
- 从重载运算符返回引用,并使用临时对象返回表达式
- Cin 对象返回值 c++
- 将变量作为类对象返回
- 使用可更改对象返回只读的最佳方法是什么
- 如何在Cython中从另一个包装对象返回包装的c++对象
- 当对象返回时,c++动态数组被清除
- 从带有动态字段的函数、对象返回
- 从堆栈上的匿名对象返回对*this的引用