在本网站上说明:http://www.tutorialspoint.com/cplusplus/cpp_variable_scope.htm
在函数或块内声明的变量是本地的 变量。它们只能由其中的语句使用 功能或代码块。函数不知道局部变量 在他们自己之外。
然后,在下面的例子中;
class foo {
/*....*/
};
foo bar(){
foo f;
return f;
}
void main(){
foo fooReturn = bar();
}
bar()
何时返回,fooReturn
包含有效对象?是:
类似于foo f
的{{1}}都是堆上的对象吗?
感谢 丹尼尔
答案 0 :(得分:2)
不,foo f;
与foo * f = new foo();
非常不同,因为前foo
是在堆栈上构建的,它的析构函数在超出范围时会自动调用,等等。 />
相反,后者foo
构建在堆上,需要手动销毁调用delete
等。
但是,在您的示例代码中,返回的foo f
是已复制或已移动(如果foo
提供移动语义,例如移动构造函数) ,超出函数bar()
。所以你有一个有效的对象返回给调用者。
注意强>
更准确地说,C ++编译器可以应用优化,即RVO (Return Value Optimization),可以避免复制或移动返回的foo
。
答案 1 :(得分:1)
bar()
何时返回,fooReturn
包含有效对象?
因为返回表达式(f
)的值用于在销毁之前初始化fooReturn
。只要类型具有正确的复制/移动语义,或者省略了复制/移动,结果对象就会有效。
是:
foo f
类似于foo *f = new foo();
都是堆上的对象吗?
不,第一个是自动变量,存储在函数的堆栈框架中,当它超出范围时会被销毁。第二个是动态对象,存储在堆上,如果没有明确的delete
,则不会被销毁。
答案 2 :(得分:0)
从函数返回本地对象时,将创建一个副本(使用复制结构函数)。在您的示例中,fooReturn
包含f
对象的副本(bar
的本地)。复制f
后,它将被释放。