C ++返回对临时[duplicate]的引用

|                                                                                                                   这个问题已经在这里有了答案:                                                      
已邀请:
如果您的函数如下所示:
AnotherObject& getAnotherObject()
{

    . . .

    Object::const_iterator it = find (\"lang\");
    if (it == this->end()) { return AnotherObject() };

    . . .

}
问题是您返回的AnotherObject()将在函数退出后立即销毁,因此函数的调用者将引用虚假对象。 但是,如果您的函数按值返回:
AnotherObject getAnotherObject()
然后在原件销毁之前先进行复印,您会没事的。     
return AnotherObject();
创建一个对象,该对象在函数退出之前被破坏-临时对象在包含它们的表达式[*]的末尾被销毁,and3ѭ表达式创建一个临时对象。 由于该函数按引用返回,这意味着调用者甚至有机会看到该引用,因此不再引用有效对象。 如果该函数按值返回就可以了,因为临时变量将被复制[**]。 [*]有几种情况无法解决,但在这里却无济于事。 [**]实际上,有一个名为“复制构造函数删除”的优化,这意味着不需要创建,复制和销毁临时文件。取而代之的是,在某些情况下,允许编译器以与创建临时目标相同的方式来创建副本的目标,而完全不必理会临时目标。     
您正在堆栈
AnotherObject()
上创建一个临时值,并在销毁它之前立即返回它。您的函数的调用者将获得垃圾,因此被禁止。 也许您想在堆上分配它并返回指向它的指针?
return new AnotherObject();
或者,声明您的函数以将\“ copy \”返回到您的对象,而不是像我假设您现在正在返回的引用一样:
AnotherObject f()
{
  return AnotherObject();  // return value optimization will kick in anyway!
}
    
必须声明该函数以返回引用,并且引用必须引用在函数退出后将继续存在的对象。返回之后,您的临时\“ AnotherObject()\”就会被销毁,因此显然无法正常工作。如果您不能更改方法签名,则可能需要引发异常而不是返回错误值。     
您应该将函数的返回类型从\“ AnotherObject&\”更改为\“ AnotherObject \”,然后按值返回该对象。否则它将像Blindy所述     
您不应返回对在行末​​尾被销毁的临时目录的引用,也不应返回对在函数末尾被销毁的局部区域的引用。 如果要保留当前签名,则必须添加一个静态常量实例,您可以将其作为默认值返回。
#include <iostream>

template <class T>
class X
{
    T value;
    static const T default_instance;
public:
    X(const T& t): value(t) {}
    const T& get(bool b) const
    {
        return b ? value : default_instance;
    }
};

template <class T>
const T X<T>::default_instance = T();

int main()
{
    X<int> x(10);
    std::cout << x.get(true) << \' \' << x.get(false) << \'\\n\';
}
您也可以按值返回或返回指针,在这种情况下,可以返回NULL。     
调用AnotherObject \的构造函数会在堆栈上创建一个新实例,该方法返回时会立即销毁该实例。 如果查找失败,创建并返回新对象很可能不是一个好主意。调用代码将无法判断返回的对象是否是数据结构中存在的先前存在的对象。 如果确实要执行此操作,则应将新对象添加到数据结构中,然后在数据结构中返回指向新对象的迭代器。 像这样:
if (it == this->end()) {
    it = this->insert(pair<ExString, AnotherObject>( string, AnotherObject() ));
    return  it->second; 
}    
    
我个人认为这有点麻烦,但是只要您确实坚持返回的引用的常量,您就应该能够返回一个静态构造的AnotherObject实例,该实例的唯一原因是\“为函数的“找不到”返回值。例如,使其成为类Object的静态const私有成员,并且只要其他对象的默认构造实例不是要包含在Object实例中的有效值,就可以了。     

要回复问题请先登录注册