-1

I have written a piece of code where I have an abstract base class. Class Tiger and Class Lion are inheriting from Animal Base Class virtually. Liger is inheriting from both Lion and Tiger. When I try to create an object of Liger and access walk function , I get the error "ambiguous access of walk". I have used virtual inheritance to avoid diamond problem. Can anyone help me to overcome this problem.

#include "stdafx.h"
#include <iostream>
using namespace std;
class Animal
{
public:
    virtual void walk() = 0;

};
class Lion : virtual public Animal
{
public:
     void walk()
    {
        cout<<"Animal Walking"<<endl;
    }
};
class Tiger : virtual public Animal
{
public:
    void walk()
    {
        cout<<"Animal Walking"<<endl;
    }
};
class Liger : public Lion , public Tiger
{
public:

};


int _tmain(int argc, _TCHAR* argv[])
{
    Liger lig;
    lig.walk();
    return 0;
}

1 Answers1

1

Since you have 2 methods with the same definition, the compiler doesn't know which to use. You can explicitly tell the compiler which to use. For example this uses the definition from Tiger:

lig.Tiger::walk();

Unfortunately the given program is still malformed:

You simply are not allowed to have a situation in which a virtual function has more than one final overrider in any derived class that exists in your program.

from this answer for a similar question.

Alternatively you could provide a definition for walk() in the Liger class, which would also allow you to call either of the derived functions. Here's the given sample modified to work using this:

#include <iostream>

class Animal
{
public:
    virtual void walk() = 0;
};

class Lion : virtual public Animal
{
public:
    void walk()
    {
        std::cout << "Lion walking" << std::endl;
    }
};
class Tiger : virtual public Animal
{
public:
    void walk()
    {
        std::cout << "Tiger walking" << std::endl;
    }
};

class Liger : public Lion, public Tiger
{
public:
    void walk()
    {
        std::cout << "Liger walking" << std::endl;
    }
};


int main()
{
    Liger liger;
    liger.walk();

    // Note that you can also access other derived classes' walk functions
    liger.Tiger::walk();

    return 0;
}
Community
  • 1
  • 1
tambre
  • 4,625
  • 4
  • 42
  • 55
  • Since you have an actual `Liger`, `liger.walk()` [will complie](http://coliru.stacked-crooked.com/a/13f83616bc7e032d) – NathanOliver Aug 23 '16 at 18:01