【问题标题】:How to inherit specific variables from different classes inherited from one base class?如何继承从一个基类继承的不同类的特定变量?
【发布时间】:2021-01-20 20:22:21
【问题描述】:

我有一个基类 A、2 个子类 B 和 C,它们都继承自 A,我有一个继承自 B 和 C 的类 D,我想从 B 中获取 _a,从 C 中获取 _b,而不必如果可能的话,为 print_a 和 print_b 做一个虚拟方法

# include <iostream>

class A
{
    public:

    A(void) : { }
    ~A(void) { }

    inline void print_a(void) { std::cout << _a << std::endl; }
    inline void print_b(void) { std::cout << _b << std::endl; }


    protected:

    int _a;
    int _b;
};

class B : virtual A
{
    public:

    B(int a) : A() { _a = a, _b = 0; }
    ~B(void) { }

    protected:

    using A::_a;
    using A::_b;
};

class C : virtual A
{
    public:

    C(int b) : A() { _a = 0, _b = b; }
    ~C(void) { }

    protected:

    using A::_a;
    using A::_b;
};

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

    D(void) : A(), B(5), C(5) { }
    ~D(void) { }


    private:

    using B::_a;
    using C::_b;
};

int main(void)
{
    D foo;

    foo.print_a();
    foo.print_b();
    return (0);
}

我的 D 类从 A 继承方法 print_a 和 print_b,我希望它从 B 继承 _a = 5 和从 C 继承 _b = 5,但它不起作用,它输出:

0
5

代替:

5
5

【问题讨论】:

  • 您可以通过将 D 的定义更改为 class D : virtual public A, private C, private B 来修复它,但如果重新排序会更改输出,您就是在玩火。这是一个带有该更改的示例:onlinegdb.com/XOMzDDI8f
  • @JerryJeremiah 这是我的错误,我写了 { _a = a, _b = 5; } 而不是 { _a = a, _b = 5; },我想要做的是将成员 B::_a 复制到 D::_a 和 C::_b 到 D::_b

标签: c++ class inheritance


【解决方案1】:

当您将virtual 用于所有基类时,您最终会得到D 只有一个A(而不是一个作为D 的基类,一个作为B 的基类,一个作为基类C)。

问题在于你的构造函数。

派生类的构造函数按照基类列表中给出的顺序调用所有基类的构造函数,因此在您的情况下D::D 调用:

A::A() -> _a and _b uninitialized
B::B(5)
  _a = 5
  _b = 0
C::C(5)
  _a = 0
  _b = 5

目前尚不清楚您为什么要在不同的构造函数中多次设置 _a_b。最好在构造函数的成员初始化器列表中初始化成员,而不是在构造函数主体中分配它。例如你可以写

A(int a, int b) : _a(a), _b(b) {}
B(int a) : A(a, 0) {}
C(int b) : A(0, b) {}
D() : A(5, 5), B(5), C(5) {}

这里D::D()会导致

A(5, 5) -> _a initialized to 5, _b initialized to 5
B(5) -> no effect (on A/_a/_b)
C(5) -> no effect (on A/_a/_b)

如果您想坚持您的设计并初始化构造函数主体中的变量,您只需将代码添加到D::D 以覆盖基类构造函数设置的任何内容:

D() : A(), B(5), C(5) { _a=5; _b=5; }

【讨论】:

  • 编辑:构造函数 B 是 _a = 5,_b = 0,而不是 b = 5,只取 b 中的 _a 和 c 中的 _b
  • 好的,那么我该如何在不调用 B 和 C 构造函数的情况下从 B 继承 _a 和从 C 继承 _b 呢?它会出现语法错误
  • 您不能从 A 的一部分继承,只能从完整的 A 继承。您的根本问题是什么?你想达到什么目标?我订阅的方法有什么问题?另外你似乎误会了,B 中没有 _a,C 中没有 _b,只有一个 A 有 _a 和 _b。
  • 我想要做的是例如有一个类 Human,有 2 个孩子 Warrior 和 Thief,例如将健康变量设置为战士 100 和小偷 80,以及速度变量为小偷设置为 10,为战士设置为 5,然后我想创建一个具有战士的健康和小偷的速度的 SuperWarrior 类,这就是为什么我不能在基类中初始化 _a 和 _b 跨度>
  • 好的,这让我很好理解,谢谢。在那种情况下,我提出的解决方案会奏效。重要的是你不要在B和C的构造函数中对_a和_b进行赋值,你需要在A::A中初始化_a和_b。试试我的解决方案,如果你能在调试器中运行它并逐步完成它。
猜你喜欢
  • 2012-05-16
  • 1970-01-01
  • 1970-01-01
  • 2023-03-18
  • 1970-01-01
  • 1970-01-01
  • 2018-08-13
  • 2013-11-10
  • 2020-06-06
相关资源
最近更新 更多