当前位置:  开发笔记 > 编程语言 > 正文

钻石继承和纯虚函数

如何解决《钻石继承和纯虚函数》经验,为你挑选了1个好方法。

想象一下标准的钻石继承.A类定义纯虚函数fx,B类定义fx的实现,C和D类对fx不执行任何操作.当试图在类D的实例上调用fx时,你会得到'模糊函数调用'错误,尽管只有一个fx实现.这可以通过以虚拟方式从A继承的B和C来解决.这是问题的正确解决方案吗?虚拟继承如何处理虚函数表的合并?

A --->乙---> d

\ --->Ç------ ^



1> Johannes Sch..:

...注意,Herb Sutter在这里写了3篇关于多重继承的优秀文章(1),这里是(2)和(3).他在大师的最星期写了一个整体的其他一大堆有用的文章在这里.强烈推荐 ...

首先,我不确定我的层次结构是否合适.我认为是这样的:

struct A {
    virtual void F() = 0;
};

struct B : A { void F() { } };
struct C : A { };
struct D : B, C { };

嗯,D是抽象的,因为A在D类型的对象中有两个子对象:一个B通过B的格子具体化,一个在格子中仍然是抽象的C.我认为你有一个指针D,试着打电话F.是的,出现歧义,因为编译器F在两个不同的格子中找到两个函数:

D -> B::F
D -> C -> A::F

看起来像这样:

    F()   F()
     A     A
     |     |
 F() B     C
      \   /
        D 

您可以通过虚拟派生来正式解决这种情况:

struct B : virtual A { void F() { } };
struct C : virtual A { };
struct D : B, C { };

然后你有这种情况,称为钻石继承:

       F()  
        A
      /   \
 F() B     C
      \   /
        D 

在进行查找时,它发现存在B::F重写A::F.虽然A::F仍然可以通过D::C::A,但这不再是歧义,因为它A是继承的虚拟.

这是否是您特定问题的正确解决方案 - 当然不确定.除了从类中派生虚拟之外,通常有更好的方法.关于合并虚函数表的问题 - 这完全取决于实现.GCC,据我所知D,如果我们派生虚拟,将保留指向虚拟表中的一个实例的指针.

推荐阅读
ifx0448363
这个屌丝很懒,什么也没留下!
DevBox开发工具箱 | 专业的在线开发工具网站    京公网安备 11010802040832号  |  京ICP备19059560号-6
Copyright © 1998 - 2020 DevBox.CN. All Rights Reserved devBox.cn 开发工具箱 版权所有