首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >C++对象返回

C++对象返回
EN

Stack Overflow用户
提问于 2010-12-09 23:51:23
回答 7查看 4.9K关注 0票数 7
代码语言:javascript
复制
TestObject getObject(){
    TestObject a(5.0f);
    return a;
}

int main(){
    TestObject a = getObject();
}

在C++中,返回的对象在返回时不会调用析构函数,这样说对吗?对象在函数调用中占用的内存是否在不运行析构函数的情况下被简单地删除?

好的,举一个具体的例子..

代码语言:javascript
复制
#include <iostream>

class Test{
public:
 Test(){};
 ~Test(){std::cout << "Goodbye cruel world\n";}
};


Test getAnObject(){
 Test a;
 return a;
}

int main(){
 Test a = getAnObject();
}

如果我运行它,析构函数只运行一次(不是针对getAnObject()中的本地对象)。我能假设这种情况永远都会发生吗?

代码语言:javascript
复制
#include <iostream>

class Test{
public:
 Test(){};
 ~Test(){std::cout << "Goodbye cruel world\n";}
};


Test getAnObject(){
 Test a;
 Test b;
 int i = 0;
 if (i){
  return a;
 }else{
  return b;
 }
}

int main(){
 Test a = getAnObject();
}

遵循RVO指南,此测试在getanobject()和main函数中的两个对象上运行析构函数。在这种情况下,我是否应该始终执行第三条规则以确保一致的行为?

EN

回答 7

Stack Overflow用户

回答已采纳

发布于 2010-12-10 00:11:50

如果我运行它,析构函数只运行一次(不是针对getAnObject()中的本地对象)。我能假设这种情况永远都会发生吗?

为了正确吗?不是的。为了提高效率?是。-ish。

详细说明:严格地说,本地对象在从函数返回时将被复制。然后,将通过调用本地对象的析构函数来清理本地存储。

但是,编译器可以自由地生成不同的代码,从而产生相同的可观察行为。特别是,该标准授予编译器取消复制返回值的权利,并为两个对象(返回值的本地对象和接收对象)重用相同的存储位置。在这样做时,编译器可能不需要调用复制构造函数,也不需要调用析构函数(因为它重用了相同的内存位置)。

然而,这种优化(称为“命名返回值优化”,NRVO)并不受标准的保证(事实上,它不可能在所有地方执行)。你不能假设它会为了正确而发生。特别是,您的对象仍然需要定义良好的复制构造函数和析构函数,否则程序就是病态的。

另一方面,您可以合理地期望所有现代编译器在任何可能的情况下执行这种优化。因此,从性能的角度来看,您可以(通常)依赖这种优化。

票数 9
EN

Stack Overflow用户

发布于 2010-12-09 23:54:12

它是基于实现的。它被称为返回值优化技术。有关更多信息,请查看以下内容:

http://en.wikipedia.org/wiki/Return_value_optimization

票数 5
EN

Stack Overflow用户

发布于 2010-12-09 23:53:39

getObject()会返回一份a的副本。这是如果编译器不做任何优化会发生的事情。将使用TestObject的复制构造函数创建a的临时副本。然后销毁原始的a,并调用它的析构函数,然后将临时对象复制到main()函数的局部变量a中。然后,临时函数也将被销毁,并调用其析构函数。

由于在这种特殊情况下,getObject()的返回值会立即赋值给一个变量,因此现代编译器可能能够优化至少一个复制操作。

票数 3
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/4400159

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档