0

Why is the below code not ambiguous and how it works fine?

#include <QCoreApplication>
#include <iostream>
using namespace std;

class Shape{
public:
    virtual void drawShape(){
        cout << "this is base class and virtual function\n";
    }
};

class Line : public Shape{
public:
    virtual void drawShape(){
        cout << "I am a line\n";
    }
};

class Circle : public Shape{
public:
    virtual void drawShape(){
        cout <<" I am circle\n";
    }
};

class Child : public Line, public Circle{
public:
    virtual void drawShape(){
        cout << "I am child :)\n";
    }
};

int main(int argc, char *argv[])
{
    QCoreApplication a(argc, argv);
    //Shape *s;
    //Line l;
    Child ch;
    //s = &l;
    //s = &ch;
    ch.drawShape(); // this is ambiguous right? but it executes properly!
    //s->drawShape();
    return a.exec();
}
curiousguy
  • 8,038
  • 2
  • 40
  • 58
highlander141
  • 1,683
  • 3
  • 23
  • 48
  • 1
    This is not an example of [virtual inheritance](http://stackoverflow.com/questions/21558/in-c-what-is-a-virtual-base-class), which is something totally different. – Bo Persson Dec 06 '15 at 06:44
  • @BoPersson how is it different from `virtual inheritance` ? – Ankit Acharya Dec 06 '15 at 06:46
  • 1
    well yes @BoPersson but the inheritance I've used is an example of diamond problem. I am little confused regarding "ambiguity calls" – highlander141 Dec 06 '15 at 06:46

1 Answers1

3

It isn't ambiguous because Child defines it's own override of drawShape, and ch.drawShape will call that function. If Child did not provide an override of drawShape then the call would be ambiguous.

1201ProgramAlarm
  • 32,384
  • 7
  • 42
  • 56
  • 1
    but even if I remove virtual keyword in base class, even then its working! – highlander141 Dec 06 '15 at 06:39
  • @highlander141 The base class here has nothing to do with ambiguity. It is what's known at the time of the call that makes it ambiguous as I've already explained. – 1201ProgramAlarm Dec 06 '15 at 06:41
  • 2
    `class Child : public Line, public Circle{ };` ... `Child ch; ch.drawShape();` will give the error, because the compiler won't know if you want `Line::drawShape`, `Circle::drawShape`, or both. – 1201ProgramAlarm Dec 06 '15 at 06:48
  • @highlander141 Virtual behavior is inherited by default. You are telling that you do not see a problem even after removing the keyword virtual. The keyword virtual is optional in the derived class. If not specified, any function defined as virtual in base class will by default become virtual in derived class. – Faisal Dec 07 '15 at 07:17