C++按值返回类对象经优化后的内存存储位置疑问
关于C++按值返回类对象的存储位置问题
假设有自定义类Foo,存在两个看似矛盾的结论:一是C++类对象除非通过new分配,否则绝不会在堆上;二是函数按值返回的局部类对象不一定会发生数据拷贝。针对这个疑问,结合以下代码分析对象的存储位置:
class Foo { ... } Foo a(int x) { Foo result; doabc(x, result); return result; } Foo b(int x) { Foo result = a(x); doxyz(x,result); return result; } int main() { int x; cin >> x; Foo result = b(x); dosomethingelse(result); cout << result; }
核心解答
绝不会分配到堆上
没有new/malloc这类显式堆分配操作的情况下,编译器绝对不会偷偷把对象放到堆内存中,自然也不需要自动插入delete代码。所有对象都始终在栈上。存储位置与栈帧归属
这种避免拷贝的优化是命名返回值优化(NRVO),属于C++标准允许的编译器优化。当优化生效时:- 函数
a里的局部对象result不会在a的栈帧里构造,而是直接在调用者b的栈帧中预留的result位置构造; - 同理,函数
b里的result会直接在调用者main的栈帧中预留的result位置构造。
整个过程跳过了中间的拷贝/移动操作,所有对result的修改都是直接在最终目标位置(调用者栈帧)执行,最终对象属于发起调用的函数栈帧。
- 函数
代码实际执行逻辑
编译器会重构代码,让a、b、main里的result都指向main栈帧中的同一块内存。从doabc到doxyz再到dosomethingelse,所有操作都是直接对main里的result对象进行,没有任何对象拷贝行为。
内容的提问来源于stack exchange,提问作者codepoet
相关产品推荐
相关产品推荐

