自动实例与新建 - 创建对象c ++

时间:2014-11-25 11:36:43

标签: c++

在本网站上说明: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}}都是堆上的对象吗?

感谢 丹尼尔

3 个答案:

答案 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后,它将被释放。