1

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

背景

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

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

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

问题

MyDirectory 实现覆盖了 Base 的getParent方法,该方法期望返回一个 Directory。实际上,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) {}
};
4

1 回答 1

1

协变返回类型只是方便。

GetMyParent()返回MyDirectory。推迟GetParentGeyMyParent直到MyDirectory可见,然后GetParent调用GetMyParent

如果你愿意,MyDirectory你可以GetParent完全协变,但我不会打扰。永远不要覆盖GetParentafter MyBase,如果需要覆盖GetMyParent

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

如果这使代码难以维护,请编写一个自由函数 calped GetParent,它使用覆盖来选择要调用的函数。如果您讨厌免费函数,请添加一个非虚拟方法来选择调用哪个函数(以及两个,一个 inBase和一个 in MyBase)。

自由函数/非虚拟方法的唯一问题是您的多路径树可能会混淆它,从而导致歧义。GetMyParent()当您知道有 aMyBase和需要 a时,我只会打电话MyDirectory*。对方法/自由函数的大量覆盖的要求,或者需要让 ti 自动发生的模板骇客,是不值得的。

于 2013-02-14T13:00:08.023 回答