Refrence to ... is ambigous!! / C++ - 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?

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.

This is an easy fix
remove Student from Results base class
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

Related

'class MainClass' has no member named 'procent

#include <iostream>
#include <vector>
using namespace std;
class MainClass{
public:
virtual void getData() = 0;
virtual void printData() = 0;
};
class Car : public MainClass{
private:
int hp;
int motor;
public:
Car(int _hp = 0, int _motor = 0){
hp = _hp;
motor = _motor;
}
~Car(){
cout << "The program is over";
}
void getData(){
cout << "HorsePower = ";
int _hp;
cin >> _hp;
hp = _hp;
cout << "Motor = ";
int _motor;
cin >> _motor;
motor = _motor;
}
void printData(){
cout << "HorsePower = " << hp << '\n';
cout << "Motor = " << motor << '\n';
}
float procent(){
return float(motor) / hp;
}
};
int main()
{
MainClass *p = new Car;
p -> getData();
p -> printData();
cout << p -> procent();
return 0;
}
I'm pretty new with oop concepts so why do I get the error from title and how can i solve it? I tried to put virtual float procent() = 0 in MainClass, but then i should use this function in every class that i would create next and I dont want this.
procent() is not a member of class MainClass.
The pointee type of p is MainClass.
Hence, you can only access what is known in MainClass.
That the pointer p actually holds an address of a Car instance doesn't count for this.
getData() and printData() are known but procent() not. (It's part of the derived class Car.)
That you can access Cars overridden getData() and printData() by the MainClass pointer p is a result of the (wonderful world of) polymorphy i.e. they are virtual.
So, this is a potential solution – to make procent() a virtual member function of MainClass as well.
There is still another solution but it should be used as last resort only:
You can use dynamic_cast() to check whether/that p holds actually a pointer to an instance of class Car:
#include <iostream>
#include <vector>
using namespace std;
class MainClass{
public:
virtual void getData() = 0;
virtual void printData() = 0;
};
class Car : public MainClass{
private:
int hp;
int motor;
public:
Car(int _hp = 0, int _motor = 0){
hp = _hp;
motor = _motor;
}
~Car(){
cout << "The program is over";
}
void getData(){
cout << "HorsePower = ";
int _hp;
cin >> _hp;
hp = _hp;
cout << "Motor = ";
int _motor;
cin >> _motor;
motor = _motor;
}
void printData(){
cout << "HorsePower = " << hp << '\n';
cout << "Motor = " << motor << '\n';
}
float procent(){
return float(motor) / hp;
}
};
int main()
{
MainClass *p = new Car;
p -> getData();
p -> printData();
if (Car *pCar = dynamic_cast<Car*>(p)) {
cout << pCar -> procent();
}
return 0;
}
Output:
HorsePower = 300
Motor = 6
HorsePower = 300
Motor = 6
0.02
Live Demo on coliru
The solution with dynamic_cast may be preferable for large class inheritance trees where it's merely impractical to add virtual member functions to the base class for any (exotic) specific feature of derived classes.
The error happens because your trying to access the procent() method in the MainClass object. To resolve this, you need to add it as a virtual method in the MainClass and override it in the Car object.
Plus make sure to delete the allocated memory.
#include <iostream>
#include <vector>
using namespace std;
class MainClass{
public:
virtual void getData() = 0;
virtual void printData() = 0;
virtual void procent() = 0;
};
class Car : public MainClass {
private:
int hp;
int motor;
public:
Car(int _hp = 0, int _motor = 0){
hp = _hp;
motor = _motor;
}
~Car(){
cout << "The program is over";
}
void getData() override {
cout << "HorsePower = ";
int _hp;
cin >> _hp;
hp = _hp;
cout << "Motor = ";
int _motor;
cin >> _motor;
motor = _motor;
}
void printData() override {
cout << "HorsePower = " << hp << '\n';
cout << "Motor = " << motor << '\n';
}
float procent() override {
return float(motor) / hp;
}
};
int main()
{
MainClass *p = new Car;
p -> getData();
p -> printData();
cout << p -> procent();
delete p;
return 0;
}
The reason for the error is that when you assign the data of the derived class to the base class pointer, the data accessed from the base class pointer is treated as if its from the base class. And since the method procent() is not available in it, the error is flagged.
TIP:
Even though stating override in the overridden method is not necessary, it'll definitely increase the readability of your code.

Static with classes error

this its C++.
i dont really know wheres the problem since the both of the static cast are equally typed but it only display correctly employee info, when it comes to patient info it only display date in and date out, but no person info, (employee does correctly print person info)
void *print( ){
Node *aux;
aux = this->head;
while(aux){
Employee *employee = static_cast<Employee*>(aux->getPerson());
Patient *patient = static_cast<Patient*>(aux->getPerson());
if(employee) {
employee->info();
}
else if (patient){
patient->info();
//Should be one of the cases above
}
aux = aux->getNext();
}
return 0;
just at the moment i print this, it prints only employee info but patient info its not displayed.
class Patient: public Person {
private:
int Id_Patient;
Person person;
string Date_In;
string Date_Out;
public:
Patient(){
this->Date_In;
this->Date_Out;
}
Patient (int Id_Patient, Person person){
this->Id_Patient=Id_Patient;
this->person=person;
}
Patient (int Id_Patient, Person person, string Date_In, string Date_Out){
this->Id_Patient=Id_Patient;
this->Date_Out=Date_Out;
this->Date_In=Date_In;
}
void setId_Patient(int Id_Patient){
this->Id_Patient=Id_Patient;}
int getId_Patient(){
return this->Id_Patient;}
void setDate_In(string Date_In){
this->Date_In=Date_In;}
string getDate_In(){
return this->Date_In;}
void setDate_Out(string Date_Out){
this->Date_Out=Date_Out;}
string getDate_Out(){
return this->Date_Out;}
void setPerson(Person person) {
this->person=person; }
Person getPerson() {
return this->person;}
void info() {
cout <<"=================================" << endl;
cout << "Patient ID: " << this->Id_Patient << endl;
this->person.info();
cout << "Date_In: " << this->Date_In << endl;
cout << "Date_Out: "<< this->Date_Out << endl;
cout <<"=================================" << endl;
}
}; //clase patient
class Employee: public Person {
private:
int Employee_Code;
Person person;
double Salary;
public:
Employee() {
this->Employee_Code;
this->Salary;}
Employee(int Employee_Code, Person person){
this->Employee_Code=Employee_Code;
this->person=person;
}
Employee(int Employee_Code, double Salary){
this->Employee_Code=Employee_Code;
this->Salary=Salary;
}
Employee(int Employee_Code, Person person, double Salary){
this->Employee_Code=Employee_Code;
this->person=person;
this->Salary=Salary;
}
void setEmployee_Code(int Employee_Code){
this->Employee_Code=Employee_Code;}
int getEmployee_Code(){
return this->Employee_Code;}
void setSalary(double Salary){
this->Salary=Salary;}
double getSalary(){
return this->Salary;}
void setPerson(Person person) {
this->person=person; }
Person getPerson() {
return this->person;}
void info() {
cout <<"=================================" << endl;
cout << "Employee_Code: " << this->Employee_Code << endl;
this->person.info();
cout << "Salary: " << this->Salary << endl;
cout <<"=================================" << endl;
}
}; //clase employee
It appears that OP has confused static_cast with dynamic_cast. But there is a much better way to do this that eliminates the need for any casting: add pure virtual method virtual void info()=0; to Person.
Patient and Employee's info will implement Person's info and print can simply
aux->getPerson()->info();
All done.
off topic, what point is there to returning void * from print? void * is a failure of imagination, bad planning, or an interface with a C library in C++. You should almost never use it, and certainly not to return 0.

Access Protected Function from base class using derived class object

Hi I have following code in which i am using protected inheritance
#include<iostream>
#include<string>
using namespace std;
class Animal
{
protected:
int age;
string name;
public:
void setAge(int a)
{
this->age = a;
}
void setName(string n)
{
this->name = n;
}
int getAge() const
{
return age;
}
string getName() const
{
return name;
}
};
class Dog : protected Animal
{
public:
string setBreed(string n)
{
return this->breed = n;
}
string getBreed()
{
return breed;
}
private:
string breed;
};
int main()
{
int a;
string n, b;
Dog D;
cout << "Enter the name of the Dog: ";
cin >> n;
cout << "Enter the age of the Dog: ";
cin >> a;
cout << "Enter the breed of the Dog: ";
cin >> b;
D.setName(n);//set name is not accesible
D.setAge(a);
D.setBreed(b);
cout << "The name of the animal is: " << D.getName() << endl;
cout << "The age of the animal is: " << D.getAge() << endl;
cout << "Breed of the dog: " << D.getBreed() << endl;
}
I want to access set name and get name from base class using derived class object as i am implementing protected inheritance the code doesn't compile. So how can i aceess setters and getters without using public inheritance and using derived class object?

Inaccessible base of different classes object oriented programming c++

I have been trying to compile this code. It has a class called books which and other genre of books inherit from it. However, when i compile the program it keeps saying Book is an inaccessible base of Police. Then it shows red lines under the first two add_book calls in the main where they add new Police.
I dont see where there is lack of access in my code?
#include <iostream>
#include <vector>
#include <string>
using namespace std;
class Book{
public:
virtual double calc_price()const;
Book(string t, string a, int pg, bool bs)
: title(t), author(a), pages(pg), bestseller(bs){}
virtual ~Book(){};
virtual void display() const;
protected:
string title;
string author;
int pages;
bool bestseller;
};
void Book::display() const {
cout << "Title: " << title << endl;
cout << "Author: " << author << endl;
cout << "Number of pages: " << pages << endl;
cout << "Bestseller: "; if(bestseller==true){ cout << "Yep"
<< endl; } else {cout << "Nope" << endl;
cout << "Price: " << calc_price() << endl; }
}
double Book::calc_price() const {
if(bestseller==true){ return (pages*0.3 + 50); }
else { return (pages*0.3); }}
class Roman : public Book {
public:
Roman(string t, string a, int pg, bool bs, bool bio)
: Book(t,a,pg,bs), biography(bio){}
virtual ~Roman();
virtual void display()const override;
protected:
bool biography;
};
void Roman::display() const{
Book::display();
cout << "Ce roman ";
if(biography==true){ cout << "is a biography. " << endl;
} else { cout << "isn't a biography. " << endl; }
}
class Police : Roman {
public:
Police(string t, string a, int pg, bool bs, bool bio)
: Roman(t,a,pg,bs,bio){}
virtual double calc_price() const {
double price;
price = Book::calc_price() - 10;
if(price < 0) { return 1; } else { return price; }}
virtual~Police();
};
class Fantasy : public Livre {
public:
Fantasy(string t, string a, int pg, bool bs)
: Book(t,a,pg,bs){}
virtual ~Fantasy();
virtual double calc_price() const {
return (Book::calc_price() + 30); }
};
class Library{
public:
void display() const;
void add_book(Book* l);
void empty_stock();
private:
vector<Book*> books;
};
void Library::add_book(Book* b){
books.push_back(b);
}
void Library::display() const {
for(size_t i(0); i < books.size(); ++i){
books[i]->display();
} }
void Library::empty_stock(){
for(size_t i(0); i < books.size(); ++i){
delete books[i]; } books.clear();
}
int main()
{
Library l;
l.add_book(new Police("Dogs of Baskerville", "A.C.Doyle", 221, false,false));
l.add_book(new Police("Le Parrain ", "A.Cuso", 367, true, false));
l.add_book(new Roman("Book3", "I. Calvino", 283, false, false));
l.add_book(new Roman ("Geronimoe memories", "S.M. Barrett", 173, false, true));
l.add_book(new Fantasy ("European rivers", "C. Osborne", 150, false));
l.display();
l.empty_stock();
return 0;
}
Change class Police : Roman in class Police : public Roman.
If public is not specified, the Roman will be a private base class for Police.
Change this line
class Police : Roman {
to
class Police : public Roman {

C++ test with classes

Im trying to solve a problem in C++ but because im a begginer i dont know how to do it !
The problem is this if you can help me :) :
By using the below C++ code create the proper constructor functions about the classes "car" & "truck". Each function must pass the appropriate arguments to the parent class of vehicle.Additionally, the function car should initialize the passengers when creating an object. The truck class should initialize the loadlimit when creating an object.
The statement of objects with the car () and truck () will be as follows:
car ob(passengers, wheels, range);
truck ob(loadlimit, wheels, range);
#include <iostream>
using namespace std;
class vehicle{
int num_wheels;
int range;
public:
vehicle(int w, int r){num_wheels = w; range = r;}
void showv(){
cout << "Wheels: " << num_wheels << endl;
cout << "Range: " << range << endl;
}
};
class car : public vehicle {
int passengers;
public:
void show(){
void showv();
cout << "Passengers: " << passengers << endl;
}
};
class truck : public vehicle {
int loadlimit;
public:
void show(){
void showv();
cout << "Loadlimit: " << loadlimit << endl;
}
};
int main(){
car c(5, 4, 500);
truck t(3000, 12, 1200);
cout << "Car: " << endl;
c.show();
cout << "Truck: " << endl;
t.show();
return 0;
}
Class Car and Truck does not have constructors that take required parameters and pass to the base class's constructor. they should be like this:
class car : public vehicle {
int passengers;
public:
car(int w,int r,int p): vehicle(w,r), passengers(p){}
void show(){
void showv();
cout << "Passengers: " << passengers << endl;
}
};
class truck : public vehicle {
int loadlimit;
public:
truck(int r, int w, int l):vehicle(r,w),loadlimit(l){}
void show(){
void showv();
cout << "Loadlimit: " << loadlimit << endl;
}
};
Base member initialisation
Car Constructor:
car(int a, int b, int c) : vehicle(a,b),passengers(c){}; //initialiser list
Truck Constructor:
truck(int g, int h, int j):vehicle(g,h),loadlimit(j){}
You need to add a Contractor to car and truck
class car : public vehicle {
int passengers;
public:
car(int p) : vehicle(int w, int r) // Call the superclass constructor in the subclass'
{
passengers = p;
}
void show()
{
showv();
cout << "Passengers: " << passengers << endl;
}
};
The same thing for Truck
Simple Solution,
car::car(int w,int r,int p)
{
passengers = p;
vehicle::vehicle(w,r);
}