如何使用智能指针的协变返回类型? [英] How can I use covariant return types with smart pointers?

查看:448
本文介绍了如何使用智能指针的协变返回类型?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我有这样的代码:

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.


  1. 我做错了什么?

  2. 如果没有,为什么是这样的语言 - 它应该是可扩展的,以处理这种情况下智能指针之间的转换?是否有一个理想的解决方法?


推荐答案

首先,这是它在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.

如果您的界面<> RetInterface 足够全面,那么你不需要知道调用代码中的实际返回类型。一般来说,它没有意义:原因 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屋!

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