Home > database >  Base class is an ambiguous base of derived class
Base class is an ambiguous base of derived class

Time:12-22

I am having trouble understanting how to differentiate between multiple instances of the base class in a multiple inheritance situation. When looking for solutions, i only found answers about virtual inheritance but that does not solve my problem at all, since i do not want to have a single instance of the base in the final class at the end of the inharitance tree.

On wikipedia, the first paragraph states that:

Without virtual inheritance, if two classes B and C inherit from a class A, and a class D inherits from both B and C, then D will contain two copies of A's member variables: one via B, and one via C. These will be accessible independently, using scope resolution.

but i did not find any info on how to use scope resolution in my situation.

As for my task, the (forced and overcomplicated) class hierarchy is:

class Vehicle
{
    protected:
        unsigned long uPrice;
        char* szOwner; // for some reason, not allowed to use std::string in my homework...
    public:
        unsigned long GetPrice();
        // ...
}

class Trailer : public Vehicle
{
    protected:
        unsigned long uWid;
        unsigned long uHei;
        unsigned long uLen;
        unsigned long uMaxWeight;
    public:
        // ...
};

class Car : public Vehicle
{
    protected:
        unsigned long uWid;
        unsigned long uHei;
        unsigned long uLen;
        char* szBrand;
    public:
        // ...
};

class Trailer_Car : public Trailer, public Car
{
    private:
        unsigned long uTotalMass;
    public:
        // ...
};

As i stated above, i want multiple instances of Vehicle in an instance of Trailer_Car (one for Car and one for Trailer). And this works completly fine for:

Trailer_Car c(/*...*/, 3500, 1200);
std::cout << c.Trailer_Car::Car::GetPrice() << "\n"; // prints 3500
std::cout << c.Trailer_Car::Trailer::GetPrice();  // prints 1200

However, in my code i have to sort an inhomogeneous array (which can contain any of the 4 classes) and casting a Trailer_Car into Vehicle results in error: 'Vehicle' is an ambiguous base of 'Trailer_Car'. Example:

Vehicle** Arr = new Vehicle*[N];
// ...

Arr[i] = static_cast<Vehicle*>(new Trailer_Car); // error: 'Vehicle' is an ambiguous base of 'Trailer_Car'

How can i solve this? I know the error comes from the fact that Arr[i] doesen't know to which Vehicle from Trailer_Car to point but still nothing C like comes to mind.
As i am more used to C i would just make Arr a void** altough i do not know how good of a practice that is in C and i am asking this to avoid doing C in C .

CodePudding user response:

You can use an intermediate conversion of the pointer type to control which instance of the repeated base class you get

Arr[i] = upcast<Car*>(new Trailer_Car);

or

Arr[i] = upcast<Trailer*>(new Trailer_Car);

I recommend to avoid a "real cast" for something that should be an implicit conversion. It won't force the compiler to do stupid things and shut up, the way a cast often will.

template<typename S, typename T> S upcast(const T& t) { return t; }

This way either of these lines gives you an implicit conversion with explicitly specified destination type, followed by an implicit conversion with inferred destination type (Vehicle*).

Note that in the process of storing a pointer to one or the other of the two Vehicle subobjects, you are also selecting which data the sort logic will use.

Also, you shouldn't manage dynamic memory by hand using new and delete, but use a smart pointer. A library one or one you wrote... but follow the Single Responsibility Principle and don't put memory management in the same class as anything else.

  • Related