C ++返回类型,当我不知道它是否是临时的 [英] C++ return type when I don't know if it's temporary

查看:113
本文介绍了C ++返回类型,当我不知道它是否是临时的的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

假设 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屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆