0

I am currently learning Inheritance. The code below works just fine.

#include <iostream>

class Student {
protected:
    double GPA = 3.12;
};

class Employee {
protected:
    int Salary = 1500;
};

class TeachingAssistant: public Student, public Employee {
public: 
    void Print() {
        std::cout << GPA << " " << Salary << "\n";
    }
};

int main() {
    TeachingAssistant TA;
    TA.Print();
}

However this code below does NOT work.

#include <iostream>

class Student {
protected:
    double GPA = 3.12;
};

class Employee: public Student {
protected:
    int Salary = 1500;
};

class TeachingAssistant: public Student, public Employee {
public: 
    void Print() {
        std::cout << GPA << " " << Salary << "\n";
    }
};

int main() {
    TeachingAssistant TA;
    TA.Print();
}

The Error

I only changed one thing in between these two code snippets and it's the addition of "public Student" next to the class Employee. What did I do wrong? Please explain this using simple words/logic.

  • 1
    Post the error that you're getting. – Jason Sep 17 '22 at 15:00
  • Most likely: https://stackoverflow.com/questions/2659116/how-does-virtual-inheritance-solve-the-diamond-multiple-inheritance-ambiguit – orhtej2 Sep 17 '22 at 15:00
  • TeachingAssistant is inheriting from Student twice (once directly and once via Employee) so the reference to GPA is ambiguous, it could refer to either of the Students you are inheriting from. – john Sep 17 '22 at 15:03
  • In fact looking at the error message it describes exactly what I said in the comment above. Was there something specifically you didn't understand about the error? – john Sep 17 '22 at 15:05
  • Does this answer your question? [Fixing C++ Multiple Inheritance Ambiguous Call](https://stackoverflow.com/questions/18158094/fixing-c-multiple-inheritance-ambiguous-call) – The Dreams Wind Sep 17 '22 at 15:06
  • Side note: [Does it make sense for `Employee` to be a `Student`](https://en.wikipedia.org/wiki/Liskov_substitution_principle)? – user4581301 Sep 17 '22 at 15:08
  • @john I think I understand now. So basically its inheriting the same thing twice creating duplicates of its data members and member functions, so when I tried to cout GPA it has two of them and the computer didn't know which one to print. – imheretolearn Sep 17 '22 at 15:10
  • Taken from [ask], with no added emphasis: "**DO NOT post images of code, data, error messages, etc.**" You should copy the error message as text, so that it can be found by the next person with the same issue, assuming they [search for the error message](https://stackoverflow.com/search?q=%5Bc%2B%2B%5D+inaccessible+due+to+ambiguity). – JaMiT Sep 17 '22 at 16:14
  • @imheretolearn That's right, this is the normal behaviour when inheriting. However there is also something called virtual inheritance which changes this default. No doubt you'll learn about that later. – john Sep 17 '22 at 17:40

2 Answers2

1

Field GPA can be accessed from class TeachingAssistant by two ways:

TeachingAssistant -> Student  
TeachingAssistant -> Employee -> Student

You must specify which one you need
For example:

std::cout << Employee::GPA << " " << Salary << "\n";

Another solution is to remove the other inheritance of class Student:

class TeachingAssistant: public Employee {
public:
    void Print() {
        std::cout << GPA << " " << Salary << "\n";
    }
};
zalevskiaa
  • 174
  • 5
1

Your situation is the following: you have a teaching assistant who's an Student (1) and Employee (2) - however the Employee based on your design is also a student. You end up by having teaching assistant being two students and one employee. C++ is telling which student's you want me to print the GPA for, hence the ambiguous.

The design is simply wrong in the second code snippet.

TeachingAssistant is both an Employee and a Student: Yes.
An Employee is a Student: No.

Oussama Ben Ghorbel
  • 2,132
  • 4
  • 17
  • 34