c++ - 在 C++ 中用不完整的派生类覆盖方法返回类型

标签 c++ multiple-inheritance

我正在用 C++ 编写一个“文件系统”抽象,具有以下继承层次结构:

 [Node]
   ^
   |
   +----[Dir]
   |
   +----[File]

Node 定义了与两者相同的所有行为(名称、上次修改时间等)但是,我有一个名为 getParent() 的 Node 方法 返回类型 Dir *。这很好用,因为虽然 Dir.h 显然需要知道 Node.h 中的实现规范,但 Node.h 不需要了解 Dir.h 中的内容,以便我可以使用前向声明。太好了。

但是,我最近决定添加多重继承,这样我就可以在特定时间支持文件系统的“快照”。这些是“实时”Node FileDir 类的只读版本,并且由于实时版本可以从写入,我让每个实时版本都继承了它的快照双重:

[NodeSnapshot] <------ [Node]
    ^                    ^
    |                    |
    +---[DirSnapshot]<---+---[Dir]
    |                    |
    +---[FileSnapshot]<--+---[File]

因此,Dir继承自NodeDirSnapshotFile继承自FileSnapshot 节点。到目前为止一切看起来都很好,直到我们到达 getParent() 的声明。在 NodeSnapshot 中,我返回一个 DirSnapshot *。没问题,我可以再次使用前向声明。但是,在 Node 中,我想返回 Dir *。作为程序员,我知道 DirDirSnapshot 的子类型,但是编译器无法知道这一点,因为前向声明没有任何有用的信息嵌入其中的信息。

是否可以通知编译器这个前向声明是一个子类,因此它不应该告诉我 Dir::getParent() 的返回类型与 DirSnapshot::getParent()?

最佳答案

可以在没有任何语言支持的情况下实现/模拟返回类型协变,尽管解决方案往往很冗长。另一方面,相互递归定义是没有问题的。需要使用调用虚拟私有(private)函数的非虚拟公共(public)(内联)函数。这是一种有用的技术,有些人甚至认为所有接口(interface)都应该这样实现。

这是一个例子:

// forward declare classes
class A;
class B;
class AA;
class BB;

// parents
class A
{
    virtual B* getB_impl();
public:
    B* getB() { return getB_impl(); }
};
class B
{
    virtual A* getA_impl();
public:
    A* getA() { return getA_impl(); }
};

// kids
class AA : public A
{
    virtual BB* getBB_impl();
    B* getB_impl();
public:
    BB* getB() { return getBB_impl(); }
};
class BB : public B
{
    virtual AA* getAA_impl();
    A* getA_impl();
public:
    AA* getA() { return getAA_impl(); }
};

// implement parents
B* A::getB_impl() { return new B; }
A* B::getA_impl() { return new A; }

// implement kids
B* AA::getB_impl() { return getBB_impl(); }
BB* AA::getBB_impl() { return new BB; }
A* BB::getA_impl() { return getAA_impl(); }
AA* BB::getAA_impl() { return new AA; }

// check
A a; B b;
A* pa; B* pb;
AA aa; BB bb;
AA* paa; BB* pbb;

pa = b.getA();
pb = a.getB();

pa = bb.getA();
pb = aa.getB();

paa = bb.getA();
pbb = aa.getB();

关于c++ - 在 C++ 中用不完整的派生类覆盖方法返回类型,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/13968220/

相关文章:

c++ - C++中的多级继承和调用基础构造函数

scala - 可以重命名基类中的 Scala 方法吗?

C++/Qt - QGraphicsItem 的多重继承没有按预期工作

c++ - 多重继承 : using a member function of a private base

c++ - 如何在 C++ 中的 basic_string 中有空值

c++ - 计算出多少客户端可以连接到我正在使用的某些tcp服务器代码

c++ - 将函数声明为 BigStruct&& foo(...) 是一种好习惯吗?

c++ - __builtin__FUNCTION() 是否有 MSVC 等价物?

c++ - WORD 的 cmpxchg 比 BYTE 快

Django 的 MutiTable 对比。抽象继承