C++ class multiple inheritance error - c++

I have been working on multiple inheritance. I have made a program but it keeps giving me an error such as Human::getInfo is ambiguous. How do I solve the problem
here is my code
#include <iostream>
#include <string>
using namespace std;
class Man{
protected:
std::string name;
public:
void getInfo(string hName){
name = hName;
}
void showInfo(){
std::cout << "Your name is: " << name << std::endl;
std::cout << "And you are a MAN" << std::endl;
}
};
class Women:public Man{
public:
Women(){}
void Women_showInfo(){
std::cout << "Your name is: " << name << std::endl;
std::cout << "And you are a Women" << std::endl;
}
};
class Human:public Women, public Man{
public:
Human(){}
};
int main(){
//local variables
string choice;
string name;
//class object
Human person;
//user interface
cout << "What your name: " ;
cin >> name;
cout << "Are you a [boy/girl]: ";
cin >> choice;
//saving name
person.getInfo(name); //ambiguous
//if handler
if (choice == "boy"){
person.showInfo(); //ambiguous
}else if(choice == "girl"){
person.Women_showInfo(); //works fine no error
}
system("pause");
return 0;
}
Also feel free to make changes in my code and would be even better if your could point out my mistake using my code.

Your design is rather questionable, but the particular ambiguity arises because Human inherits from both Woman and Man, but Woman already inherits from Man.
So Human has two getinfo() functions in it - Human::Man::getinfo() and Human::Woman::Man::getinfo(). Unless you tell the compiler which one to use it doesn't know, and thus reports an error.

Related

how can i use aggregation while separating my classes into a .h and .cpp files?

Context
My professor gave me a task to make a program using aggregation between 2 classes while also separating the classes into a .h and .cpp files.
My solution
The header file containing the class declaration:
#include <iostream>
#include <string>
using namespace std;
class medicalCompany {
private:
string ceoName;
string email;
string phoneNumber;
string locate;
public:
medicalCompany();
void Name(string n);
void mail(string m);
void phone(string p);
void location(string l);
~medicalCompany();
};
class origin {
private:
medicalCompany country;
public:
origin();
void address();
~origin();
};
and my .cpp file:
#include <iostream>
#include "function.h"
#include <string>
using namespace std;
medicalCompany::medicalCompany() {
cout << "OUR COMPANY IS GLAD TO BE OF SERVICE !" << endl;
cout << "****************************************************" << endl;
}
void medicalCompany::Name(string n){
ceoName = n;
cout << "OUR CEO IS " << endl;
cout<< ceoName << endl;
cout << "****************************************************" << endl;
}
void medicalCompany::mail(string m) {
email = m;
cout << "USE OUR EMAIL TO CONTACT US : " << endl;
cout<< email << endl;
cout << "****************************************************" << endl;
}
void medicalCompany::phone(string p) {
phoneNumber = p;
cout << "THIS IS OUR CUSTOMER SERVICE PHONE NUMBER " << endl;
cout<< phoneNumber << endl;
cout << "****************************************************" << endl;
}
void medicalCompany::location(string l) {
locate = l;
cout << " OUR COMPANY IS LOCATED IN " << endl;
cout << locate << endl;
cout << "****************************************************" << endl;
}
medicalCompany::~medicalCompany() {
cout << "thanks for trusting our company ^_^" << endl;
cout << "****************************************************" << endl;
}
origin::origin() {
cout<< "constructor 2"<<endl;
}
void origin::address() {
cout << country.location;
}
origin::~origin() {
cout << "bye" << endl;
}
The two classes are used in my main.cpp file:
#include <iostream>
#include <string>
#include "function.h"
using namespace std;
int main() {
medicalCompany o;
o.Name("jack");
o.mail("ouremail#company.com");
o.phone("2342352134");
o.location("Germany");
origin o2;
return 0;
}
Problem
I run into this error :
Severity Code Description Project File Line Suppression State
Error C3867 'medicalCompany::location': non-standard syntax; use '&' to create a pointer to member CP2_HW c:\function.cpp 41
You can either:
replace void origin::address(){cout << country.location;} by void origin::address(){country.location();}
or by void origin::address(){cout << country.locate;} if you put the locate member as a public variable.
Also, few remarks:
Generally you would prefer avoiding exposing private members, so the first solution should be prefered.
the instruction using namespace std; is usually considered bad practice, and should be avoided, as the cost of possible risks does not overweight the benefit of not having to type std::cout(see this question for more information)
In terms of naming convention, I would have exchanged the names of locate and location: location should be the member variable and locate the action (function) of getting the location.
Prefer using a constructor and intialization lists rather than getter/setter.
Your output formatting should be very separate from the logic of your classes, for example implementing a << operator for your class.
Following this logic, your code should look more like:
#include <iostream>
#include <string>
class medicalCompany {
private:
std::string _ceoName;
std::string _email;
std::string _phoneNumber;
std::string _location;
public:
// Constructor
medicalCompany(std::string name, std::string email, std::string phone, std::string location):
_ceoName(name),
_email(email),
_phoneNumber(phone),
_location(location)
{}
friend ostream& operator<<(ostream& os, const medicalCompany& dt);
};
and for the ostream operator:
ostream& operator<<(ostream& os, const medicalCompany& co)
{
os << co._ceoName << " " co._phoneNumber << ' ' << co._email;
return os;
}
This would allows to write code like this in your main:
int main() {
medicalCompany o("jack", "ouremail#company.com","2342352134","Germany")
std::cout << o << std::endl;
return 0;
}
The code is not functional and you would have to edit it to fit your formating requirement, but you have the idea :) Good luck!

object is undefined in function

Im new to C++ and started working with classes recently for a school excercice.
I really cant see whats wrong and after creating an object "player" to the Hero class i can't use that object later in the "main Menu" function to call a method because i get the "identifier is undefined" error!
Any suggestions?
#include "stdafx.h"
#include <iostream>
#include <string>
#include <cstdlib>
using namespace std;
class Hero
{
private:
//member variables
string playername;
public:
//constructor
Hero(string name)
{
playername = name;
}
string getName()
{
return playername;
}
};
//start 1
void mainMenu()
{
cout << " - - - |" << player.getName() << "- - - \n";
}
void setPlayer()
{
string name;
cout << "Hello, what is your name? " << endl;
getline(cin, name);
Hero player(name);
mainMenu();
}
int main()
{
int selection;
cout << "Shadow of darkness\n ";
cout << "1.) Start ";
cout << "2.) Exit ";
cin >> selection;
if (selection == 1)
setPlayer();
else if (selection == 2)
exit (0);
else
main();
return 0;
}
OK, calling main() from main() is a forbidden (as explained here), so do not do it.
Here is a typical example with your class (the class is cool as you have it, I just added an initializer list for fun):
#include <iostream>
#include <string>
using namespace std;
class Hero
{
private:
//member variables
string playername;
public:
//constructor
Hero(string name) : playername(name)
{
}
string getName()
{
return playername;
}
};
int main()
{
Hero player("Daniel");
cout << "Player's name: " << player.getName() << std::endl;
return 0;
}
Output:
Player's name: Daniel
Based on this, try to work your logic and do all sort of stuff that you long for (after reading some books/tutorials)!

C++ Error (operand types are 'std::string and 'void')

1st of all Im newBee at C++ programming.so please apologize if i make lots of mistake while asking questions.
My problem is:
i create class which contain private variable and Methods like below:
class Records{
private:
string name;
public:
string n;
void setValue(){
cout << "Enter name" << endl;
cin >> name;
}
void getValue(){
n = name;
cout << "Name is: " << n << endl;
}
};
I have run your code on GCC compiler, it's successfully worked. Please, see complete example :
#include <iostream>
using namespace std;
class Records{
private:
string name;
public:
string n;
void setValue(){
cout << "Enter name" << endl;
cin >> name;
}
void getValue(){
n = name;
cout << "Name is: " << n << endl;
}
};
int main()
{
Records r;
r.setValue();
r.getValue();
}

arry of pointers ( classes )

So I have these classes:
In main I wrote an array of pointers:
student *arry[10];
How can I make each cell point to an object of a different class?
For example :
I want the cell 0 , 2 , 4
point to an object of class medstudent
using ( new statement )
thank you
here is class medStudent
#include<iostream>
#include"student.cpp"
using namespace std;
class medStudent:public student {
public :int clinicH;
public:
medStudent(int ch, string n , int i ):student(n,i){
setClinicH(ch);
cout << "New Medecine Student" << endl;
}
~medStudent(){
cout << "Medecine Student Deleted" << endl;
}
medStudent(medStudent & ms):student(ms){
cout << "New Copy Medecined Student" << endl;
}
medstudent(){
}
void setClinicH(int ch){
clinicH = ch;
}
int getClinicH()const{
return clinicH;
}
void print()const{
student::print();
cout << "Clinical Hours: " << getClinicH() << endl;
}
};
Here is class student:
#include <iostream>
//#include"medstudent.cpp"
using namespace std;
class student//:public medstudent
{
public :
static int numberOfSaeeds;
const int id;
string name;
public:
~student(){
cout << "Delete Student: " << getName() << " " << endl ;
}
student(string n, int i):id(i){
setName(n);
cout << "Student with args" << endl ;
}
void setName(string n){
name = n;
}
string getName()const{
return name;
}
void print()const{
cout << "My name is: " << name << endl;
cout << "My ID is: " << id << endl;
}
void setNOS(int nos){
numberOfSaeeds = nos;
}
int getNOS(){
return numberOfSaeeds;
}
void printAddress()const{
cout << "My address is " << this << endl;
}
student * getAddress(){
return this;
}
student(student & sc):id(sc.id){
name = sc.name;
setName(sc.getName());
cout << "New Object using the copy constructor" << endl;
}
};
Here is main code:
#include<iostream>
using namespace std;
#include"time.cpp"
#include "student.cpp"
//#include"medstudent.cpp"
int main(){
student a1("asa" , 2);
student * a[10];
a[3]= new student("jj", 22 );
a[0] = new medStudent();
}
Since you explicitly declare a medStudent constructor the compiler will not create a default constructor for your class. And when you do new medStudent(); you are (explicitly) trying to invoke the default constructor, which doesn't exist.
That will give you a build error, one that should have been very easy to diagnose if you read it and most importantly shown it to us (when asking questions about build errors, always include the complete and unedited error output, including any informational output, in the body of the question, together with the code causing the error).
The solution? Call the existing parameterized constructor. E.g. new medStudent("foo", 123).
By the way, if you want inheritance to work okay, and the base-class destructor to be called when deleting an object of a child-class, then you need to make the destructors virtual.

How do I fix "Member is ambiguous" error?

I use Borland C++ 4.5 as my school recommends it.
When I try to run this code, I get three errors when I try to run the code.
I try to change the access specifier every time, but I fail.
#include "iomanip.h"
#include "iostream.h"
#include <conio.h>
#include <stdio.h>
class person
{
public:
int code;
char name[50];
void PEnter()
{
cout << "\nEnter Code :\n";
cin >> code;
cout << "\nEnter Name :\n";
gets(name);
}
};
class account : public person
{
public:
float pay;
void AcEnter()
{
cout << "\nEnter Pay :\n";
cin >> pay;
}
};
class admin : public person
{
public:
int experience;
void AdEnter()
{
cout << "\nEnter Experience :\n";
cin >> experience;
}
};
class master : public account, admin
{
public:
void MEnter()
{
PEnter();
AcEnter();
AdEnter();
}
void MRet()
{
cout << setw(20) << name << "\t" << setw(7) << code << "\t"
<< setw(6) << pay << "\t" << setw(3) << experience << "\n";
}
};
void main()
{
clrscr();
master M[200];
int i = 0;
char ch;
do {
M[i].MEnter();
++i;
cout << "\nEnter More :\n";
cin >> ch;
} while (ch == 'Y' || ch == 'y');
int j = i;
clrscr();
cout << setw(20) << "Name\t" << setw(7) << "Code\t" << setw(6)
<< "Pay\t" << setw(3) << "\tExperience\n";
for (i = 0; i <= j; ++i) {
M[i].MRet();
}
getch();
}
These are the three errors that I get:
Error NONAME00.CPP 43 : Member is ambiguous 'person::PEnter' and 'person::PEnter' in function master::MEnter()
Error NONAME00.CPP 49 : Member is ambiguous 'person::name' and 'person::name' in function master::MRet()
Error NONAME00.CPP 49 : Member is ambiguous 'person::code' and 'person::code' in function master::MRet()
I do not know whether the class person is being inherited or not (by the master class).
You hit the diamond inheritance problem. What it is and how to solve it described here virtual inheritance Note inheritance in the wiki example is very close to yours so there should not be any problem for you to follow solution provided there
One can also inherit the base class as virtual
class admin : public virtual person
class account : public virtual person
call the fn as
person::PEnter();
input the value like this -
person::name;
person::code;