Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Fixing C++ Multiple Inheritance Ambiguous Call

I have three classes structured like this:

#include <iostream>
using namespace std;

class Keyword
{
    public:
        virtual float GetValue() = 0;
};

class CharacterKeyword : public Keyword
{
    public:
        virtual float GetValue(){return _value;}
    private:
        float _value;
};

class MeasurementKeyword : public Keyword
{
    public:
        virtual float GetValue(){return _value;}
    private:
        float _value;
};

class AddressType : public CharacterKeyword, public MeasurementKeyword
{

    private:
        float address;
        float addresExt;
};

int main()
{
    AddressType *a = new AddressType();
    a->GetValue();
    return 0;
}

I am getting the following:

In function ‘int main()’:
error: request for member ‘GetValue’ is ambiguous
error: candidates are: virtual float Keyword::GetValue()
error: virtual float MeasurementKeyword::GetValue()
error: virtual float CharacterKeyword::GetValue()

I have done some reading into multiple inheritance and I know that it has a lot of pitfalls - this being one of them. I need my class structure to be like this so I was wondering if there was a way that I could fix this using templates?

Update
After reading your comments, my original thought was that maybe I can just delineate between an AddressType that is a CharacterKeyword and an AddressType that is a MeasurementKeyword by templating the AddressType. And using it as such in the updated code. OR I can just specify the namespace of the member that I would like. Since the templated way has not been mentioned yet as an answer, is it a bad fix? Should I just specify the namespace of the member I want?

template <class T>
class AddressType : public T
{

    private:
        float address;
        float addresExt;
};

int main()
{
    AddressType<MeasurementKeyword> *a = new AddressType<MeasurementKeyword>();
    a->GetValue();
    return 0;
}
like image 825
larrylampco Avatar asked Aug 10 '13 02:08

larrylampco


People also ask

How can we resolve ambiguity in multiple inheritance?

Ambiguity in inheritance can be defined as when one class is derived for two or more base classes then there are chances that the base classes have functions with the same name. So it will confuse derived class to choose from similar name functions. To solve this ambiguity scope resolution operator is used “::”.

Does multiple inheritance lead to ambiguity?

Inheritance Ambiguity in C++ In multiple inheritances, when one class is derived from two or more base classes then there may be a possibility that the base classes have functions with the same name, and the derived class may not have functions with that name as those of its base classes.

Why is multiple inheritance not allowed in Java?

Java doesn't support multiple inheritances in classes because it can lead to diamond problem and rather than providing some complex way to solve it, there are better ways through which we can achieve the same result as multiple inheritances.

Which type of inheritance leads to ambiguity problem?

Namely Single Inheritance, Multiple Inheritance, Hierarchical Inheritance, Multilevel Inheritance, Hybrid Inheritance (also known as Virtual Inheritance). Function ambiguity will arise only when a more than one base class are inherited in derived class.


1 Answers

This is because of a diamond inheritance pattern, to resolve the error you can specify the specific namespace you want the member from like.

paddressType->MeasurementKeyword::GetValue()

or

paddressType->CharacterKeyword::GetValue()  

  1. Basically your AddressType class has access to the GetValue members from both the classes it inherits from and can't choose one (call is ambiguous).
  2. The scope resolution operator (:: ) helps specify which one you actually want.
  3. You haven't said what you actually want this code to do so I'll just say that generally complex inheritance patterns are not conducive to creating readable code, rethink what you actually want.
like image 91
aaronman Avatar answered Sep 23 '22 19:09

aaronman