繁体   English   中英

带有指针的C ++无效协变返回类型

[英]c++ invalid covariant return type with pointer

我已经进行了大量搜索以找到解决问题的方法,但是我找不到使以下代码正常工作的方法。

背景

我写了一个表示任何类型的Archive的类结构(在我的实际情况下,这将是FileRepository,也可能是Archive)。 因此,我定义了一个代表存档的纯虚拟类结构。

档案实际上是一个目录,目录实际上是一个实体(在这种情况下为Base)。 该存档中的文件也将是一个实体(基础)。 这些类用作实际实现的接口。

在代码中,您将看到这些类的My ...实现。

问题

MyDirectory实现覆盖了Base的getParent方法,该方法希望返回目录。 实际上,MyDirectory实现只能将MyDirectory作为父级,因此新实现将返回MyDirectory,而不返回Directory。 这就是C ++抛出错误消息的地方!

编译器不知道MyDirectory实际上一个目录,因为在声明MyDirectory类之前,我覆盖了MyBase类中的getParent方法。

而且由于MyDirectory也想调用特定的MyDirectory方法(如getAbsolutePath),因此我确实需要将返回类型设置为MyDirectory,而不是Directory。 (并且static_cast无效,或者:()

我很高兴有任何提示,如何解决我的问题:)

编辑:详细信息

问题实际上是复杂的继承图。 问题是MyDirectory继承了MyBase,但是MyBase的方法返回MyDirectory-但是Base类需要返回Directory,但是在声明时,c ++不知道MyDirectory实际上是Directory。 我正在尝试解决,MyDirectory可以返回MyDirectory实例,而无需返回Directory实例。

// Just an example code - actually is separated in .h and .cpp and cleaner and and and... :)

class Directory;
class MyDirectory;

class Base {
public:
    /// Returns the parent directory
    virtual Directory *getParent()=0;
};

class Directory : virtual public Base {
public:
};

class Archive : virtual public Directory {
public:
};

// ---------------------------------

class MyBase : virtual public Base {
public:
    /// Constructor
    MyBase(int i, int j, int k) {}

    /// Returns the parent directory
    MyDirectory *getParent() { return NULL; }

    /// Returns the parent directory
    virtual const char *getAbsolutePath() const { return "my full path"; }
};

class MyDirectory : virtual public Directory, public MyBase {
public:
    /// Constructor
    MyDirectory(int i, int j) : MyBase(i, j, i+j) {}

    /// Returns the parent directory (not really, I know! Just an example)
    virtual const char *getAbsolutePath() const { return getParent()->getAbsolutePath(); }
};

class MyArchive : virtual public Archive, public MyDirectory {
public:
    /// Constructor
    MyArchive(int i) : MyDirectory(i, i) {}
};

协变量返回类型只是方便。

编写GetMyParent()返回MyDirectory GetParentGeyMyParent的实现推迟到MyDirectory可见之前,然后让GetParent调用GetMyParent

如果需要,在MyDirectory可以使GetParent完全协变,但是我不会打扰。 切勿在MyBase之后重写GetParent ,如果需要,请重写GetMyParent

也许将GetParent私有,这样就不会意外调用它。 如果您有MyBase ,请改为调用GeyMyParent

如果这使代码难以维护,请编写一个免费的函数Calped GetParent ,该函数使用重写选择要调用的函数。 如果您讨厌自由函数,请添加一个非虚拟方法,该方法选择要调用的方法(两种方法,一种在Base ,一种在MyBase )。

自由功能/非虚拟方法的唯一问题是您的多路径树可能会混淆它,从而造成歧义。 当您知道拥有MyBase并需要MyDirectory*时,我只想调用GetMyParent() 对于方法/自由功能的大量替代要求,或者要求ti自动发生的模板黑客行为,是不值得的。

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM