Наследовать от двух родительских классов (которые наследуются от одного базового класса), но некоторые методы не работают - PullRequest
1 голос
/ 12 января 2020

У меня проблемы с некоторыми методами после наследования. Трудно (для меня) сказать, где именно проблема, но я попытаюсь показать это на примере.

Минимальный код:

#include <iostream>

class A
{
public:
    A() {};
    A(int x):val(x)
    {
        std::cout << "A constructor work" << std::endl;
    }

    int get()
    {
        std::cout << "Get A work" << std::endl;
        return val;
    }

protected:
    int val; 
};

class B: protected A
{
public:
    B(int x) :A(x) 
    {
        std::cout << "B constructor work" << std::endl;
        test();
    }

    int get()
    {
        std::cout << "Get B work" << std::endl;
        return A::get();
    }

protected:
    void test()
    {
        if (A::val == 0)
        {
            std::cout << "Test B work" << std::endl;
            A::val = 1;
        }
    }

};

class C : protected A
{
public:

    C() {};
    C(int x) :A(x)
    {
        std::cout << "C constructor work" << std::endl;
        test();
    }

    int get()
    {
        std::cout << "Get C work" << std::endl;
        return A::get();
    }
protected:
    void test()
    {
        std::cout << "Test C work" << std::endl;

        if (A::val != 0)
        {
            A::val += 2;
        }
    }

};

class D : private B, private C
{
public:
    D(int x):B(x)
    {
        std::cout << "D constructor work" << std::endl;
        C::test();
    }

    int get()
    {
        std::cout << "Get D work" << std::endl;
        return B::get();
    }

};


int main()
{
    D d(0);

    std::cout << d.get() << std::endl;
}


Output: 
**A constructor work
B constructor work
Test B work
D constructor work
Test C work
Test C extra work
Get D work
Get B work
Get A work
1**

Я ожидаю, что val = 3 в конец, но это так не работает. Буду особенно признателен за подробный ответ.

1 Ответ

0 голосов
/ 12 января 2020

Ваш class D содержит два A объекта - один унаследованный B и один унаследованный C

Когда вы вызываете C::test(), вы меняете объект A в C.

Когда вы звоните D::get() - который вызывает B::get() - вы проверяете значение объекта A в B.


Один способ получить обойти это можно посредством виртуального наследования . Это не то, с чем вы хотите связываться, пока не поймете, как работает множественное наследование.

...