Mohammadreza Sarijlou
Mohammadreza Sarijlou

Reputation: 11

Refrence to ... is ambigous!! / C++

#include <iostream>

using namespace std;

class Student
{
protected:
    long studentID;
public:
    void setStudentID(long s_){ studentID = s_; }
    Student(): studentID(0){}
    long get_StudentID(){ return studentID; }
};

class Exam : public Student
{
protected:
    float mark;
public:
    void setMark(float m_){ mark = m_; }
    Exam(): mark(0){}
    float getMark(){ return mark; }
};

class Sports : public Student
{
protected:
    float score;
public:
    void setScore(float s_){ score = s_; }
    Sports(): score(0){}
    float getScore(){ return score; }
};

class Result: public Student, public Exam, public Sports
{
private:
    float Total;
public:
    float getTotal(){ return getMark() * getScore(); }
    void display();
};

void Result::display()
{
    cout << "Student ID = " << get_StudentID() << endl;
    cout << "Exam Mark = " << getMark() << endl;
    cout << "Sports Score = " << getScore() << endl;
    cout << "Total Mark = " << getTotal();
}

int main()
{
    Result st1;
    st1.display();
    return 0;
}

I wrote this code in Code::Blocks and it's incomplete yet , but this error that says "refrence to get_StudentID is ambigous" confused me; What's wrong with it? Should I delete using namespace and insert std:: before all (cout, cin & endl) statments?

Upvotes: 1

Views: 93

Answers (2)

Offtkp
Offtkp

Reputation: 410

You are misunderstanding inheritance. For example, the class Exam with this line

class Exam : public virtual Student

is publicly inheriting from Student. Public inheritance should only be used in an IS-A relationship. In this case, Exam is not a Student so you shouldn't use public inheritance. Same goes for Sports.

"Call is ambiguous" means that when you call get_StudentID from Result the compiler can't decide between Exam::get_StudentID or Sports::get_StudentID which they both inherit from Student.

Instead:
Remove the inheritance, don't use inheritance anywhere here. I would completely remake this and make a Student class with Exam and Sports member objects (which can become vector of objects later if needed) and call the needed functions from the member objects instead. As a general tip, avoid multiple inheritance unless completely necessary.

Upvotes: 2

user8143588
user8143588

Reputation:

This is an easy fix

  1. remove Student from Results base class
  2. make Student public virtual from both Exam and Sports class
#include <iostream>

using namespace std;

class Student
{
protected:
    long studentID;
public:
    void setStudentID(long s_){ studentID = s_; }
    Student(): studentID(0){}
    long get_StudentID(){ return studentID; }
};

class Exam : public virtual Student
{
protected:
    float mark;
public:
    void setMark(float m_){ mark = m_; }
    Exam(): mark(0){}
    float getMark(){ return mark; }
};

class Sports : public virtual Student
{
protected:
    float score;
public:
    void setScore(float s_){ score = s_; }
    Sports(): score(0){}
    float getScore(){ return score; }
};

class Result: public Exam, public Sports
{
private:
    float Total;
public:
    float getTotal(){ return getMark() * getScore(); }
    void display();
};

void Result::display()
{
    cout << "Student ID = " << get_StudentID() << endl;
    cout << "Exam Mark = " << getMark() << endl;
    cout << "Sports Score = " << getScore() << endl;
    cout << "Total Mark = " << getTotal();
}

int main()
{
    Result st1;
    st1.display();
    return 0;
}

Godbolt: https://godbolt.org/z/4f5n8M5of

Upvotes: 0

Related Questions