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

标签 c++ oop g++

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

背景

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

文件实际上是一个目录,目录实际上是一个实体(在本例中为 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) {}
};

最佳答案

协变返回类型只是为了方便。

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

MyDirectory 中,如果您愿意,您可以使 GetParent 完全协变,但我不会费心。切勿在 MyBase 之后重写 GetParent,如果需要,请重写 GetMyParent

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

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

free function/non-virtual method 唯一的问题是你的多路径树会混淆它,导致歧义。当您知道有一个 MyBase 并且需要一个 MyDirectory* 时,我会直接调用 GetMyParent()。对方法/自由函数进行大量覆盖的要求,或者自动发生 ti 所需的模板 hackery,是不值得的。

关于C++无效的协变返回类型与指针,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/14874080/

相关文章:

c++ - 如何使用专用线程类MyThreadClass

c++ - 哪些语言标准允许忽略固定大小数组上的空终止符?

c++ - GTest,仅参数化测试用例

c++ - 禁用 C++ vector 的边界检查

c++ - std::map 的自定义分配器失败

c++ - 默认情况下函数返回值是常量(右值)吗?

java 对象 - 公共(public)行为与静态行为

对象的 add() 方法的 Java ArrayList 不起作用

java - 为什么我应该在 Java 中的这种情况下使用接口(interface)?

makefile - 要包含或包含自动生成的依赖项?