Inherit from two parents with same members

Viewed 295

I have three classes; A, B and C:

class A
{
    public:
        A() {}
    protected:
        int x = 0;
        int y = 0;
};

class B
{
    public:
        B() {}
    protected:
        int x = 1;
        int y = 1;
};

class C : public A, B
{
    public :
        C() {}
};

I want x member of C to be the one from A, and y member of C to me that from B. How can I do this? Since I've written class C : public A, B, now both C.x and C.y are 0. I have this problem in general when I have multiple inheritance and I want to inherit some members from one parent and some members from the other. Is there an option similar to the one for member functions, where one can use the keyword using to choose which function will be used?

3 Answers

now both C.x and C.y are 0

Actually, C::x and C::y are both ambiguous and won't compile. You can explicitly select and expose members from base classes with using:

class C : public A, B
{
    public :
        C() {}

        using A::x;
        using B::y;
};

I want to inherit some members from one parent and some members from the other.

That you can't do. All members will be inherited. C has A::x,A::y, B::x and B::y.

Is there an option similar to the one for member functions, where one can use the keyword using.

You can help the compiler to resolve the ambiguity (see Quentin's answer) but the fact is that you still inherit all of the members.

class C : public A, B {
public :
    using A::x;
    using B::y;

    C() {
        std::cout << x << '\n';    // 0
        std::cout << y << '\n';    // 1

        // these are still here though:
        std::cout << A::x << '\n'; // 0
        std::cout << A::y << '\n'; // 0
        std::cout << B::x << '\n'; // 1
        std::cout << B::y << '\n'; // 1
    }
};

I want to inherit some members from one parent

It isn't possible to inherit "some members". You can only inherit a base in its entirety. In the example, the class C indirectly contains both C::A::y and C::B::y as well as the two x members.

now both C.x and C.y are 0.

Actually, now there is no C::x nor C::y because those names are ambiguous.

is there an option similar to the one for member functions, where one can use the keyword using

Yes, you can use using to make the names C::x and C::y unambiguous. It will hide the "unused" names, but the objects don't go away. Same as with member functions.


You should change the design. You could do something like this for example:

struct Ax {
    int x = 0;
};
struct Ay {
    int y = 0;
};
struct A : Ax, Ay {};

struct Bx {
    int x = 1;
};
struct By {
    int y = 1;
};
struct B : Bx, By {};

struct C : Ax, By {};
Related