【问题标题】:Returning a temporary object and using its reference [duplicate]返回一个临时对象并使用它的引用[重复]
【发布时间】:2013-09-08 12:41:33
【问题描述】:

假设我有这个方法可以创建std::vector< std::string > 类型的对象

const std::vector< std::string > Database::getRecordNames() {
    // Get the number of recors
    int size = this -> getRecordCount();

    // Create container
    std::vector< std::string > names;

    // Get some strings
    for ( i = 0; i < size; i++ ) {
        // Get a string
        const std::string & name = this -> getName( i );

        // Add to container
        names.push_back( name );
    }

    // Return the names
    return names;
}

然后在别的地方,我用这个方法

void Game::doSomething() {
    const std::vector< std::string > & names = mDatabase -> getRecordNames();

    // Do something about names
}

因此,在方法@​​987654326@ 上,它返回一个临时对象std::vector&lt; std::string &gt;。但是,在 Game::doSomething() 方法上,我将返回值放在了 const std::vector&lt; std::string &gt; &amp; 类型的对象中。

这是不安全的,还是像这样使用它们完全正常? AFAIK,临时变量在其范围结束时被销毁。但是在我们的例子中,我们引用了这个临时变量,我相信它在返回值后会被销毁。

重写另一个方法是否更好,以便它使用返回值的副本而不是引用?

void Game::doSomething() {
    const std::vector< std::string > names = mDatabase -> getRecordNames();

    // Do something about names
}

【问题讨论】:

  • 临时值被销毁...... except 当它们没有被销毁时。你所拥有的是例外,它是安全的。将临时值绑定到 const-reference 会将临时值的生命周期延长到引用变量的生命周期。
  • @KerrekSB 假设变量在Game::doSomething() 之后停止使用,它会自动销毁吗?
  • @LanceGray:我的意思是我所说的:临时值的生命周期与其绑定的引用变量的生命周期相同。

标签: c++


【解决方案1】:

按值返回向量是非常安全的。当您将其分配给 const 引用时,编译器会保持由 Database::getRecordNames() 返回的临时值有效,直到引用所在的范围结束。这就是定义 const 引用的绑定属性的方式。

【讨论】:

【解决方案2】:

只要您按值返回而不是按引用返回,它是完全安全的。只要引用在范围内,C++ 编译器就会为您保留临时对象。

【讨论】:

  • 编译器与这些有什么关系?
  • 嗯,这似乎是采用 C++ 并将其翻译成机器语言的组件。除其他外,它插入释放堆栈对象(添加或减去堆栈指针寄存器)或允许重用它们(如果它们在寄存器中)的机器代码。它几乎定义了 C++ 语言是什么以及做什么。
  • 我想说 C++ 语言定义了编译器应该做什么。
  • @juanchopanza 我同意。所做的事情(例如“让临时对象保持活动状态”)由编译器完成。
  • 如果它符合标准 WRT 这个特性:) 编译器并不总是正确的。
猜你喜欢
  • 1970-01-01
  • 2012-07-18
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2020-11-19
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多