我有这样的代码:
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 {...}
...
};
此代码无法编译。
在视觉工作室它提出
C2555:覆盖虚函数返回类型不同且不是协变的
如果我不使用 boost::shared_ptr
但返回原始指针,则代码编译(我知道这是由于 C++ 中的 协变返回类型)。我可以看到问题是因为 boost::shared_ptr
的 Ret1
不是从 boost::shared_ptr
的 RetInterface
派生的但是我想返回 boost::shared_ptr
的 Ret1
用于其他类,否则我必须在返回后强制转换返回值。
- 难道我做错了什么?
- 如果不是,为什么这种语言是这样的——在这种情况下处理智能指针之间的转换应该是可扩展的?是否有理想的解决方法?
原文由 amit kumar 发布,翻译遵循 CC BY-SA 4.0 许可协议
首先,这确实是它在 C++ 中的工作方式:派生类中的虚函数的返回类型必须与基类中的相同。有一个特殊的例外是,一个返回指向某个类 X 的引用/指针的函数可以被一个返回指向从 X 派生的类的引用/指针的函数覆盖,但正如您注意到的那样,这不允许 智能 指针(例如
shared_ptr
),仅用于普通指针。如果你的接口
RetInterface
足够全面,那么你不需要知道调用代码中实际返回的类型。一般来说,无论如何它都没有意义:原因get_r
是virtual
函数首先是因为您将通过指针或对基类的引用来调用它AInterface
,在这种情况下,您无法知道派生类将返回什么类型。如果您使用实际的A1
引用来调用它,您可以在A1
中创建一个单独的get_r1
函数来满足您的需求。或者,您可以使用访问者模式或类似我的 Dynamic Double Dispatch 技术将回调传递给返回的对象,然后该对象可以调用具有正确类型的回调。