我正在阅读 Java to C++ crash course ,除此之外,它还讨论了 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
}
这不起作用,因为 aLocalFooInstance
离开范围并被销毁。很好,对我来说很有意义。现在作为该问题的一种解决方案,给出以下代码:
Foo FooFactory::createFoo(int a, int b)
{
return Foo(a, b); // returns an instance of Foo
}
我不明白的是:为什么第二个示例是有效的 C++ 代码?这两个示例中的基本问题是否不相同,即创建了 Foo 的实例,该实例会超出范围,因此当我们从方法返回时会被销毁?
最佳答案
假设我们有代码
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 中,将从悬空引用进行初始化。
关于c++ - 在 C++ 中什么时候可以返回类实例?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/40796016/