我正在尝试减少主要使用C ++开发的应用程序的内存占用,而我正在研究的内容是通过引用返回特别大的数据结构而不是按值返回它们。我需要一些确认。例如,假设我在类some_object
中有成员函数,如下所示:
const some_type& get_some_type(...) {
...;
return ...;
}
vs
const some_type get_some_type(...) {
...;
return ...;
}
我的理解是否正确通过调用后者(通过值返回)赋值将在应用程序执行期间的某些点处在内存中留下数据some_type
的两个副本,同时调用前者(通过引用返回)避免这个?
作为减少内存占用总体目标的一部分,另一项努力是改变some_type
的定义,以避免使用上面的引用返回选项。在这种情况下,因为some_type
(实际上是类型的容器,比如类型data_type
的数据)在循环内使用,如下所示:
const some_type& = some_object->get_some_type(); // returns by ref. a large container
for(...) {
...;
data_type = some_type.at(...);
...;
}
我假设如果我们被限制使用上面的返回值,那么我需要通过引入一个新函数get_some_type_at
来按如下方式进行更改,以便按值获取容器的元素(是否有任何值)这样做的缺点,我应该知道,比如性能?):
for(...) {
...;
data_type = some_object->get_some_type_at(...); // returns by value a small object
...;
}
我再次主要是为了确认这些方面。但是最了解细节和见解。感谢您的时间和兴趣!
答案 0 :(得分:3)
大多数优秀的编译器实现返回值优化,因此您无需担心复制对象的不必要构造。
因此,选择
some_type get_some_type(...) {
...;
return ...;
}
除非你使用旧的编译器。
(确认为juanchopanza;同时删除const对象返回;注释中的解释。)
有关详情,请参阅http://en.wikipedia.org/wiki/Return_value_optimization;没意思在这里重复这个。
答案 1 :(得分:2)
我的理解是正确的,通过调用后者(按值返回)的赋值会在应用程序执行期间的某些点在内存中留下两个数据some_type副本,而调用前者(通过引用返回)会避免这种情况吗? p>
使用现代编译器的机会相当渺茫。该标准特别祝福了所谓的返回值优化(以及命名的返回值优化),让编译器避免在这种情况下创建额外的副本。我所知道的每一个合理的现代编译器都包含这种优化。在某些情况下(例如,gcc),当您告诉编译器不进行优化时,他们会执行此优化甚至。启用优化后,您必须查看10年(可能更多)的内容才能找到没有执行此操作的编译器。
C ++ 11增加了“移动”功能,可以做更多的事情来确保解决你所关心的问题,即使按值返回大对象也是如此。
底线:看起来就像你在错误的地方看到的那样 - 你可能想考虑在你的班级中添加一个显式的移动构造函数(可能还有移动赋值运算符),但总的来说,你可以只返回通过价值和快乐。