【问题标题】:C++ Multiple Inheritance - why you no work?C++ 多重继承 - 为什么你不工作?
【发布时间】:2011-05-03 02:27:04
【问题描述】:

我正在尝试找出一个有趣的多重继承问题。

祖父是一个接口类,有多个方法:

class A
{
public:
    virtual int foo() = 0;
    virtual int bar() = 0;
};

还有一些抽象类正在部分完成这个接口。

class B : public A
{
public:
    int foo() { return 0;}
};

class C : public A
{
public:
    int bar() { return 1;}
};

我要使用的类继承自两个父类,并通过 using 指令指定应该来自哪里的方法:

class D : public B, public C
{
public:
    using B::foo;
    using C::bar;
};

当我尝试实例化 D 时,我在尝试实例化抽象类时遇到错误。

int main()
{
    D d; //<-- Error cannot instantiate abstract class.

    int test = d.foo();
    int test2 = d.bar();

    return 0;
}

谁能帮我理解这个问题以及如何最好地利用部分实现?

【问题讨论】:

  • 在菱形图案中,您需要使用虚拟继承。但我不相信这会自行解决您的问题。

标签: c++ inheritance multiple-inheritance diamond-problem


【解决方案1】:

您没有钻石继承权。 DBC 基类都有自己的 A 基类子对象,因为它们实际上不继承自 A

所以,在D 中,实际上有四个纯虚成员函数需要实现:来自BA::fooA::bar 以及来自CA::fooA::bar

您可能想要使用虚拟继承。类声明和基类列表如下所示:

class A
class B : public virtual A
class C : public virtual A
class D : public B, public C

如果你不想使用虚继承那么你需要重写D中的另外两个纯虚函数:

class D : public B, public C
{
public:
    using B::foo;
    using C::bar;

    int B::bar() { return 0; }
    int C::foo() { return 0; }
};

【讨论】:

    【解决方案2】:

    您需要使您的基类virtual 才能正确继承。一般规则是所有非私有成员函数和基类都应该是virtual,除非您知道自己在做什么并且想要禁用该成员/基的正常继承。

    【讨论】:

    • "一般规则是所有公共成员函数和基类都应该是虚拟的" 什么?那是谁的一般规则?如果有的话,关于虚拟成员函数的一般规则是将它们设为私有,并在基类中有一个公共的非虚拟成员函数调用私有虚拟成员函数(这在 GotW 文章 "Virtuality" 中进行了讨论)。至于虚拟基类……我只能想到最近几年我需要使用虚拟继承的一个案例。
    • @JamesMcNellis "我只能想到过去几年我需要使用虚拟继承的一个案例。" 你需要多少次 使用-虚拟继承?
    • @JamesMcNellis:那篇文章大部分都是废话。关于它唯一正确的是大多数成员函数(虚拟或非虚拟)应该是私有的。拥有公共的非虚拟成员函数是一场等待发生的灾难,基本上意味着该类不能被子类化。
    • @ChrisDodd 你在说什么......伙计,如果你说出你个人的想法,至少不要假装你所说的是事实......gtkmm只是C++ 类的众多示例之一,其中只有几个虚函数,通常是受保护的,并且这些类仍然完全意味着子类化(并且它们被子类化非常容易)。如果你更喜欢让你的所有公共方法都是虚拟的——那很好。我不喜欢它,但我不会告诉你如何编写代码。只是不要将个人习惯传递给其他人,就好像它们是事实一样......
    猜你喜欢
    • 1970-01-01
    • 2011-02-21
    • 2011-03-17
    • 2011-03-24
    • 1970-01-01
    • 2011-04-15
    • 1970-01-01
    • 2011-03-25
    • 2015-02-12
    相关资源
    最近更新 更多