c++ - 在 C++ 中什么时候可以返回类实例?

标签 c++

我正在阅读 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 对象非常重要。

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

  1. 当计算 return 语句中的表达式 Foo(a, b) 时,会创建一个 Foo 类型的临时对象。
  2. 对 return 语句中的表达式求值后,返回值本身将从该表达式初始化。这会导致创建另一个 Foo 类型的临时文件。
  3. 第 1 步中创建的临时文件将被销毁。
  4. 第 2 步中创建的临时值是调用函数中函数调用表达式 FooFactory::createFoo(0, 0) 的结果。该临时对象用于初始化非临时对象 foo
  5. 第 2 步中创建的临时文件被销毁。

在存在复制省略和返回值优化的情况下,两个临时变量都有可能被省略。

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

关于c++ - 在 C++ 中什么时候可以返回类实例?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/40796016/

相关文章:

c++ - 如何在 C++ 中处理不同的模板参数?

c++ - 将双指针作为参数传递给需要引用 std::vector<double> 的函数

c++ - std::bind 和 std::function 问题

c++ - 跳过迭代器

c++ - 从字符串到 Ice::ByteSeq 的转换

c++ - 具有不同类型的 STL 谓词

c++ - C2864 编译器错误

c++ - Qt 应用程序在退出时崩溃,操作系统应用 "fault tolerant heap shim"

c++ - 变体 bstr 到 std::string 转换的默认编码

C++从文件中读取并标记数据