如何将协变返回类型与智能指针一起使用?

新手上路,请多包涵

我有这样的代码:

 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_ptrRet1 不是从 boost::shared_ptrRetInterface 派生的但是我想返回 boost::shared_ptrRet1 用于其他类,否则我必须在返回后强制转换返回值。

  1. 难道我做错了什么?
  2. 如果不是,为什么这种语言是这样的——在这种情况下处理智能指针之间的转换应该是可扩展的?是否有理想的解决方法?

原文由 amit kumar 发布,翻译遵循 CC BY-SA 4.0 许可协议

阅读 695
2 个回答

首先,这确实是它在 C++ 中的工作方式:派生类中的虚函数的返回类型必须与基类中的相同。有一个特殊的例外是,一个返回指向某个类 X 的引用/指针的函数可以被一个返回指向从 X 派生的类的引用/指针的函数覆盖,但正如您注意到的那样,这不允许 智能 指针(例如 shared_ptr ),仅用于普通指针。

如果你的接口 RetInterface 足够全面,那么你不需要知道调用代码中实际返回的类型。一般来说,无论如何它都没有意义:原因 get_rvirtual 函数首先是因为您将通过指针或对基类的引用来调用它 AInterface ,在这种情况下,您无法知道派生类将返回什么类型。如果您使用实际的 A1 引用来调用它,您可以在 A1 中创建一个单独的 get_r1 函数来满足您的需求。

 class A1: public AInterface
{
  public:
     boost::shared_ptr<RetInterface> get_r() const
     {
         return get_r1();
     }
     boost::shared_ptr<Ret1> get_r1() const {...}
     ...
};

或者,您可以使用访问者模式或类似我的 Dynamic Double Dispatch 技术将回调传递给返回的对象,然后该对象可以调用具有正确类型的回调。

原文由 Anthony Williams 发布,翻译遵循 CC BY-SA 2.5 许可协议

在 C++ 中重载方法时,您不能更改返回类型(对于非指针、非引用返回类型)。 A1::get_r 必须返回一个 boost::shared_ptr<RetInterface>

安东尼威廉姆斯有一个很好的综合 答案

原文由 Mr Fooz 发布,翻译遵循 CC BY-SA 3.0 许可协议

撰写回答
你尚未登录,登录后可以
  • 和开发者交流问题的细节
  • 关注并接收问题和回答的更新提醒
  • 参与内容的编辑和改进,让解决方法与时俱进
推荐问题