在C++;什么时候可以返回类实例? 我正在阅读A,另外还有一些关于C++中内存管理的文章。给出了一个示例来说明不能执行的操作: Foo& FooFactory::createBadFoo(int a, int b) { Foo aLocalFooInstance(a, b); // creates a local instance of the class Foo return aLocalFooInstance; // returns a reference to this instance }

在C++;什么时候可以返回类实例? 我正在阅读A,另外还有一些关于C++中内存管理的文章。给出了一个示例来说明不能执行的操作: Foo& FooFactory::createBadFoo(int a, int b) { Foo aLocalFooInstance(a, b); // creates a local instance of the class Foo return aLocalFooInstance; // returns a reference to this instance },c++,C++,这将不起作用,因为alocalfoodinstance离开作用域并被销毁。好吧,我觉得有道理。现在,作为该问题的一种解决方案,给出了以下代码: Foo FooFactory::createFoo(int a, int b) { return Foo(a, b); // returns an instance of Foo } 我不明白:为什么第二个例子是有效的C++代码?两个示例中的基本问题是否都不相同,即创建了Foo的实例,当我们从方法返回时,该实例将超出范围并因此被销毁?,因为

这将不起作用,因为
alocalfoodinstance
离开作用域并被销毁。好吧,我觉得有道理。现在,作为该问题的一种解决方案,给出了以下代码:

Foo FooFactory::createFoo(int a, int b) 
{
    return Foo(a, b);  // returns an instance of Foo
}

我不明白:为什么第二个例子是有效的C++代码?两个示例中的基本问题是否都不相同,即创建了

Foo
的实例,当我们从方法返回时,该实例将超出范围并因此被销毁?

,因为第二个示例通过值而不是引用返回对象

第一个示例返回对对象实例的引用,第二个示例返回对象实例

你所展示的评论甚至明确指出了这一点

在第一个示例中,只返回一个引用,被引用的对象被销毁


在第二个示例中,返回对象本身。从某种意义上说,这意味着对象“继续存在”,并且它在调用此函数的代码放置该对象的任何地方结束。

当您返回实例时,您不会延长对象的生存期,因此它会在函数的末尾大括号处被销毁,而您的引用现在没有引用任何内容


如果您返回一个类,那么该类在销毁之前会被复制到函数外部(除非RVO应用,这是一个完全不同的东西,有效地工作相同),因此您现在拥有一个创建对象的副本,该副本处于完美的工作状态,可以很好地使用。

在第二个示例中,您是(逻辑上)返回一份副本。想象一下,如果返回的是int而不是
Foo

int FooFactory::createInt(int a, int b) 
{
    return a+b;
}
你能看出这不是一个问题吗? 在C++中,一个FO将以与<代码> int >代码相同的原因工作,只要<代码> FoO 是可移动的或可复制的。< /P> < P >我们说代码

Foo FooFactory::createFoo(int a, int b) 
{
    return Foo(a, b);  // returns an instance of Foo
}

int main() {
    Foo foo = FooFactory::createFoo(0, 0);
}
区分创建的各种
Foo
对象很重要

从概念上讲,执行过程如下:

  • 当计算return语句中的表达式
    Foo(a,b)
    时,将创建类型为
    Foo
    的临时对象
  • 对return语句中的表达式求值后,返回值本身将从该表达式初始化。这将导致创建另一个类型为
    Foo
    的临时文件
  • 在步骤1中创建的临时文件将被销毁
  • 在步骤2中创建的临时变量是调用函数中函数调用表达式
    FooFactory::createFoo(0,0)
    的结果。该临时对象用于初始化非临时对象
    foo
  • 在步骤2中创建的临时文件将被销毁
  • 在存在拷贝省略和返回值优化的情况下,两个临时值都可以省略


    请注意,如果函数通过引用返回,则步骤2不会创建新对象;它只创建一个引用。因此,在第3步之后,引用的对象不再存在,在第4步中,将从悬挂引用进行初始化。

    第一个示例和第二个示例之间的主要区别是返回类型。第一个函数返回一个引用,因此对象本身不会移动到外部。第二个函数返回一个值,然后返回对象本身