gpt4 book ai didi

c++ - 菱形继承(钻石问题)和纯虚函数

转载 作者:可可西里 更新时间:2023-11-01 18:06:31 25 4
gpt4 key购买 nike

想象一下标准的菱形继承(钻石问题)。 A 类定义纯虚函数 fx,B 类定义 fx 的实现,C 类和 D 类对 fx 不做任何处理。当尝试在类 D 的实例上调用 fx 时,尽管只有一个 fx 实现,但您会收到“模糊函数调用”错误。这可以通过B和C以虚拟的方式继承A来解决。它是问题的正确解决方案吗?虚继承究竟是如何处理虚函数表合并的?

A--->B--->D

\--->C------^

最佳答案

... 注意,Herb Sutter 写了 3 篇关于多重继承的优秀文章 (1) here , (2) here(3) here .他在本周大师中写了一大堆有用的文章 here .强烈推荐...

首先,我不确定我是否正确理解了您的层次结构。我认为它是这样的:

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

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

嗯,D 是抽象的,因为在类型 D 的对象中有两个 A 子对象:一个是 B 通过 B 的格具体化的,和一个在通过 C 的格子中仍然是抽象的。我认为您有一个指向 D 的指针并尝试调用 F。是的,出现了歧义,因为编译器在两个单独的格中找到了两个函数 F:

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

看起来像这样:

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

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

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 是继承的虚拟的。

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

关于c++ - 菱形继承(钻石问题)和纯虚函数,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/457609/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com