C++ 返回对临时的引用
声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow
原文地址: http://stackoverflow.com/questions/5667161/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me):
StackOverFlow
C++ Returning reference to temporary
提问by dcinadr
Possible Duplicate:
warning: returning reference to temporary
可能重复:
警告:返回对临时的引用
I am getting the error "returning reference to temporary" on the second line below.
我在下面的第二行收到错误“返回对临时的引用”。
class Object : public std::map <ExString, AnotherObject> const {
public:
const AnotherObject& Find (const ExString& string ) const {
Object::const_iterator it = find (string);
if (it == this->end()) { return AnotherObject() };
return ( it->second );
}
}
My class implements std::map.
我的班级实现了 std::map。
I am new to C++ so I'm guessing its just a syntax error. Any help?
我是 C++ 的新手,所以我猜它只是一个语法错误。有什么帮助吗?
回答by zdan
If your function looks like this:
如果您的函数如下所示:
AnotherObject& getAnotherObject()
{
. . .
Object::const_iterator it = find ("lang");
if (it == this->end()) { return AnotherObject() };
. . .
}
the problem is that the AnotherObject() you've returned will be destroyed as soon as the function exits, and so the caller to your function will have a reference to a bogus object.
问题是您返回的 AnotherObject() 将在函数退出后立即销毁,因此您的函数的调用者将引用一个虚假对象。
If your function returned by value however:
但是,如果您的函数按值返回:
AnotherObject getAnotherObject()
then a copy will be made before the original is destroyed and you'll be OK.
然后在原件被销毁之前制作一份副本,你会没事的。
回答by Steve Jessop
return AnotherObject();
creates an object which is destroyed before function exit - temporaries are destroyed at the end of the expression that contains them[*], and the expression AnotherObject()
creates a temporary.
return AnotherObject();
创建一个在函数退出之前销毁的对象 - 临时对象在包含它们的表达式结束时被销毁 [*],并且该表达式AnotherObject()
创建一个临时对象。
Since the function returns by reference, this means that by the caller even gets a chance to see that reference, it no longer refers to a valid object.
由于函数通过引用返回,这意味着调用者甚至有机会看到该引用,它不再引用有效对象。
It would be OK if the function were to return by value, since the temporary would be copied[**].
如果函数按值返回就可以了,因为临时文件将被复制[**]。
[*] With a couple of situations that don't, but they don't help you here.
[*] 有几种情况不会,但它们在这里对您没有帮助。
[**] Actually there's an optimization called "copy constructor elision" which means the temporary needn't be created, copied and destroyed. Instead, under certain conditions the compiler is allowed to just create the target of the copy in the same way it wouldhave created the temporary, and not bother with the temporary at all.
[**] 实际上有一个叫做“复制构造函数省略”的优化,这意味着不需要创建、复制和销毁临时文件。相反,在一定条件下的编译器被允许只创建副本的目标同样的方式将所创建的暂时的,根本不与理会暂时的。
回答by Blindy
You're creating a temporary value on the stack AnotherObject()
and returning it right before it gets destroyed. Your function's caller would get garbage, and so it's forbidden.
您正在堆栈上创建一个临时值AnotherObject()
并在它被销毁之前立即返回它。你的函数的调用者会得到垃圾,所以它是被禁止的。
Maybe you want to allocate it on the heap and return a pointer to it instead?
也许你想在堆上分配它并返回一个指向它的指针?
return new AnotherObject();
Alternatively, declare your function to return a "copy" to your object, instead of a reference like I'm assuming you are returning right now:
或者,声明您的函数以将“副本”返回给您的对象,而不是像我假设您现在正在返回的引用:
AnotherObject f()
{
return AnotherObject(); // return value optimization will kick in anyway!
}
回答by UncleBens
You shouldn't return a reference to a temporary which is destroyed at the end of the line, nor a reference to a local which is destroyed at the end of the function.
您不应返回对在行尾销毁的临时对象的引用,也不应返回对在函数末尾销毁的本地对象的引用。
If you want to keep the current signature, you'd have to add a static constant instance that you can return as a default.
如果要保留当前签名,则必须添加一个可以作为默认值返回的静态常量实例。
#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';
}
You may also return by value or return a pointer in which case you can return NULL.
您也可以按值返回或返回一个指针,在这种情况下您可以返回 NULL。
回答by Ernest Friedman-Hill
The function must be declared to return a reference, and a reference has to refer to an object that will continue to exist after the function exits. Your temporary "AnotherObject()" is destructed right after the return, so that obviously won't work. If you can't change the method signature, you may need to throw an exception instead of returning an error value.
函数必须声明为返回引用,并且引用必须指向函数退出后将继续存在的对象。您的临时“AnotherObject()”在返回后立即被破坏,因此这显然行不通。如果无法更改方法签名,则可能需要抛出异常而不是返回错误值。
回答by Jurlie
You should change the return type of your function from "AnotherObject&" to "AnotherObject" and return that object by value. Otherwise it will go just like Blindy described
您应该将函数的返回类型从“AnotherObject&”更改为“AnotherObject”并按值返回该对象。否则它会像 Blindy 描述的那样
回答by ravenspoint
The call to AnotherObject's constructor creates a new instance on the stack, which is immediatly destroyed when the method returns.
调用 AnotherObject 的构造函数会在堆栈上创建一个新实例,该实例在方法返回时立即被销毁。
It is most likely not a good idea to create and return new object if the find fails. The calling code will have no way to tell if the object returned is a previously existing object present in the data structure.
如果查找失败,创建并返回新对象很可能不是一个好主意。调用代码将无法判断返回的对象是否是数据结构中存在的先前存在的对象。
If you do want to do this, then you should add the new object to the data structure and then return an iterator pointing to the new object IN THE DATA STRUCTURE.
如果您确实想这样做,那么您应该将新对象添加到数据结构中,然后返回一个指向数据结构中新对象的迭代器。
Something like this:
像这样的东西:
if (it == this->end()) {
it = this->insert(pair<ExString, AnotherObject>( string, AnotherObject() ));
return it->second;
}
回答by broc
I personally think that this is a bit of a hack, but as long as you really stick to the const'ness of the returned reference you should be able to return a statically constructed instance of AnotherObject whose only "raison d'etre" is to be the "not found" return value of your function. Make it a static const private member of your class Object for example, and you should be ok as long as a default constructed instance of AnotherObject is not a valid value to be contained in an instance of Object.
我个人认为这有点黑客,但只要你真的坚持返回引用的常量性,你应该能够返回一个静态构造的 AnotherObject 实例,其唯一的“存在理由”是成为函数的“未找到”返回值。例如,将其设为类 Object 的静态常量私有成员,只要默认构造的 AnotherObject 实例不是包含在 Object 实例中的有效值,您就应该没问题。