假设 Foo
是一个相当大的数据结构。我应该怎么写 const
返回 Foo
实例的虚函数,如果我不知道继承的类是否会存储Foo
的实例内部;因此,允许通过引用返回。如果我不能在内部存储它,我的理解是我不能返回 const
引用它,因为它将是临时的。这个对吗?这两个选项是:
virtual Foo foo() const { ... }
virtual Foo const & foo() const { ... }
这是 related question但从不同的角度。
最佳答案
您对 value return 和 const reference return 之间的区别感兴趣只是为了优化,但事实并非如此。每次返回不同的值与每次返回引用之间存在根本不同的含义,很可能指向同一个对象,很可能可以修改:
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
和另一个 float
。
您也许可以返回一个 shared_ptr
。这样,“想要”返回引用的派生类可以创建一个 shared_ptr
带有一个什么都不做的删除器(但要注意 - 如果原始对象, shared_ptr
将悬空被破坏了,这不是您通常期望从返回的 shared_ptr
中得到的。因此,如果 Foo
比它来自的对象生命周期更长是有意义的,那么它会更好类来动态分配它,通过 shared_ptr
保存它,并返回它的拷贝,而不是什么都不做的删除器)。 “想要”返回值的派生类每次都可以分配一个新值。由于 Foo
是“相当大的”,希望 shared_ptr
的成本和动态分配与你为创造新值(value)所做的事情相比不会太痛苦返回。
另一种可能性是将 Foo
变成一个小的 pImpl 样式类,该类引用一个相当大的数据结构。如果所涉及的一切都是不可变的,那么“想要返回引用”的情况可以在多个 Foo
实例之间共享大数据结构。即使不是,您也可以考虑写时复制。
关于当我不知道它是否是临时的时,C++ 返回类型,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/6505963/