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

背景

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

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

在代码中,您将看到这些类的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完全协变,但是我不会打扰。切勿在GetParent之后覆盖MyBase,如果需要,请改写GetMyParent

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

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

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

07-26 05:26