如何使用智能指针的协变返回类型? [英] How can I use covariant return types with smart pointers?
问题描述
我有这样的代码:
class RetInterface {...}
class Ret1: public RetInterface {...}
class AInterface
{
public:
virtual boost::shared_ptr<RetInterface> get_r() const = 0;
...
};
class A1: public AInterface
{
public:
boost::shared_ptr<Ret1> get_r() const {...}
...
};
此代码无法编译。在visual studio它提出C2555:覆盖虚函数返回类型不同,不是协变的。如果我不使用 boost :: shared_ptr
但返回原始指针,代码编译(我理解这是由于 C ++中的协变返回类型)。我可以看到的问题是 boost :: shared_ptr
的 Ret1
不是从 boost :: shared_ptr
的 RetInterface
。但我想返回 boost :: shared_ptr
Ret1
用于其他类,否则我必须强制返回值后返回。
This code does not compile. In visual studio it raises "C2555: overriding virtual function return type differs and is not covariant". If I do not use boost::shared_ptr
but return raw pointers, the code compiles (I understand this is due to covariant return types in C++). I can see the problem is because boost::shared_ptr
of Ret1
is not derived from boost::shared_ptr
of RetInterface
. But I want to return boost::shared_ptr
of Ret1
for use in other classes, else I must cast the returned value after the return.
- 我做错了什么?
- 如果没有,为什么是这样的语言 - 它应该是可扩展的,以处理这种情况下智能指针之间的转换?是否有一个理想的解决方法?
推荐答案
首先,这是它在C ++中的工作原理:派生类中的虚函数的返回类型必须与基类中的相同。有一个特殊的例外,返回一个引用/指针到某个类X的函数可以被返回一个引用/指针指向从X派生的类的函数覆盖,但是你注意到这不允许
Firstly, this is indeed how it works in C++: the return type of a virtual function in a derived class must be the same as in the base class. There is the special exception that a function that returns a reference/pointer to some class X can be overridden by a function that returns a reference/pointer to a class that derives from X, but as you note this doesn't allow for smart pointers (such as shared_ptr
), just for plain pointers.
如果您的界面<> get_r
是一个虚拟
函数的第一位是因为你将通过指向基类 AInterface
的指针或引用来调用它,在这种情况下,您不能知道派生类将返回什么类型。如果你用实际的 A1
引用调用这个函数,你可以在<$ c $中创建一个单独的 get_r1
If your interface RetInterface
is sufficiently comprehensive, then you won't need to know the actual returned type in the calling code. In general it doesn't make sense anyway: the reason get_r
is a virtual
function in the first place is because you will be calling it through a pointer or reference to the base class AInterface
, in which case you can't know what type the derived class would return. If you are calling this with an actual A1
reference, you can just create a separate get_r1
function in A1
that does what you need.
class A1: public AInterface
{
public:
boost::shared_ptr<RetInterface> get_r() const
{
return get_r1();
}
boost::shared_ptr<Ret1> get_r1() const {...}
...
};
或者,您可以使用访问者模式或类似于动态双重分派技术将回调传递给返回的对象,然后可以调用具有正确类型的回调。
Alternatively, you can use the visitor pattern or something like my Dynamic Double Dispatch technique to pass a callback in to the returned object which can then invoke the callback with the correct type.
这篇关于如何使用智能指针的协变返回类型?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!