C ++返回类型,当我不知道它是否是临时的 [英] C++ return type when I don't know if it's temporary
问题描述
假设 Foo
是一个相当大的数据结构。我应该如何写一个 const
虚函数返回一个实例 Foo
,如果我不知道是否继承类将在内部存储 Foo
的实例;从而允许通过引用返回。如果我不能在内部存储它,我的理解是我不能返回一个 const
引用,因为它将是一个临时的。它是否正确?这两个选项是:
Suppose that Foo
is a rather large data structure. How should I write a const
virtual function that returns an instance of Foo
, if I don't know whether the inherited classes will store the instance of Foo
internally; thus, allowing a return by reference. If I can't store it internally, my understanding is I can't return a const
reference to it because it will be a temporary. Is this correct? The two options are:
virtual Foo foo() const { ... }
virtual Foo const & foo() const { ... }
这是一个相关问题,但是角度不同。
Here's a related question but from a different angle.
推荐答案
你感兴趣的是一个值返回和一个const引用返回之间的区别只是一个优化的问题,但它不是。每次返回一个不同的值,而不是每次返回一个引用,很可能是相同的对象,这可能会被修改:
You're interested in the difference between a value return and a const reference return solely as a matter of optimization, but it isn't. There's a fundamentally different meaning between returning a different value each time, vs. returning a reference each time, quite possibly to the same object, which quite possibly could be modified:
const Foo &a = myobj.foo();
myobj.modify_the_foo();
const Foo &b = myobj.foo();
a == b; // do you want this to be true or false?
调用者需要知道它是什么,因为程序员需要知道其含义,编译器需要知道调用约定,因此不能将它们混合在同一个虚拟函数的不同覆盖中。如果一些派生类想要做一个,而另一些想要做另一个,那么这是艰难的运气,他们不能,任何不止一个可以返回 int
和另一个a float
。
The caller needs to know which it is, both because the programmer needs to know the meaning and because the compiler needs to know the calling convention, so you can't mix them in different overrides of the same virtual function. If some derived classes want to do one, and some want to do the other, then that's tough luck, they can't, any more than one can return an int
and another a float
.
您可能会返回 shared_ptr
。这样,想要返回引用的派生类可以创建一个带有删除器的 shared_ptr
,但不要执行任何操作(但要小心 - shared_ptr
如果原始对象被销毁,那么这将不会发生,这不是你通常期望从返回的 shared_ptr
。因此,如果它对于 Foo
来延长它来自的对象,它将是更好的类动态分配它,通过 shared_ptr
并返回一个副本,而不是一个无用的删除程序)。 想要返回值的派生类可以每次分配一个新的值。由于 Foo
是相当大,希望 shared_ptr
的成本和动态分配不是太痛苦
You could perhaps return a shared_ptr
. That way, the derived classes that "want" to return a reference can create a shared_ptr
with a deleter that does nothing (but beware - the shared_ptr
will dangle if the original object is destroyed, and that's not what you normally expect from a returned shared_ptr
. So if it makes sense for the Foo
to outlive the object it came from then it would be better for the class to dynamically allocate it, hold it via a shared_ptr
, and return a copy of that, rather than a do-nothing deleter). The derived classes that "want" to return a value can allocate a new one each time. Since Foo
is "rather large", hopefully the cost of the shared_ptr
and the dynamic allocation isn't too painful compared with what you'd do anyway to create a new value to return.
另一个可能性是将 Foo
变成一个引用相当大数据结构的小型pImpl样式类。如果所涉及的一切都是不可变的,那么想返回一个引用情况可以在多个 Foo
实例之间共享大型数据结构。即使不是,你可以考虑写时复制。
Another possibility is to turn Foo
into a small pImpl-style class that references a rather large data structure. If everything involved is immutable, then the "want to return a reference" case can share the large data structure between multiple Foo
instances. Even if it isn't, you can think about copy-on-write.
这篇关于C ++返回类型,当我不知道它是否是临时的的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!