Multiple class inheritance? - c++

Based on the figure below, I wrote my code.
This is the code I wrote:
#include<iostream>
#include<string>
using namespace std;
class person
{
private:
int code;
string name;
public:
void setCode(int c) { code=c; }
int getCode() { return code; }
void setName(string s) { name=s; }
string getName() { return name; }
};
class account : public person
{
private:
double pay;
public:
void setPay(double p) { pay=p; }
double getPay() { return pay; }
};
class admin : public person
{
private:
string experience;
public:
void setExper(string e) { experience=e; }
string getExper() { return experience; }
};
class master : public account, public admin
{
};
int main()
{
master mastObj;// create master object.
mastObj.setName("John");
system("pause");//to pause console screen, remove it if u r in linux
return 0;
}
The compiler showed these errors:
Error 1 error C2385: ambiguous access of 'setName'
Error 2 error C3861: 'setName': identifier not found
Error 3 IntelliSense: "master::setName" is ambiguous

It is classic example of Diamond Problem in C++ when you use multiple inheritance.
The solution is : Virtual inheritance
That is, you should do this:
class account : public virtual person
{ //^^^^^^^note this
//code
};
class admin : public virtual person
{ //^^^^^^^note this
//code
};
I just found really good posts on this site, so I would redirect you to those answers here:
Virtual inheritance in C++
Virtual Inheritance Confusion
Virtual inheritance in C++
In C++, what is a virtual base class?
which also means, this topic should be voted for close.

You need virtual inheritance:
class account: public virtual person{
....
}
class admin: public virtual person{
...
}
PS And your pay, code fields lack initialization! This could lead to embarassing errors (like paying the cleaner several million of dollars :)):
#include<iostream>
#include<string>
using namespace std;
class person
{
// ...
person() : code(0), name("anonymous") {}
};
class account : public virtual person
{
// ...
account() : pay(0) {}
};
class admin : public virtual person
{
// ...
admin() : experience("unknown") {}
};

you may use mastObj.master::admin::person::setName("John");

Related

Edit variables inherited from parent class

I have this code for a basic entity system I'm testing
Enity.h
class Enemy
{
public:
void attack(Player player);
virtual void die();
protected: //Info variables
int attackDamage;
std::string name;
bool alive;
}
class ChildEnemy1 : public Enemy
{
name = "Enemy1" //Invalid
};
class ChildEnemy2 : public Enemy
{
name = "Enemy2" // Invalid
};
How would you change the Info variables (attackDamage, name, alive) without inheriting a public setter function
(retain encapsulation).
EDIT: This is not a duplicate question as I have not found an adequate answer to this problem on SO
Initialize the members in the constructor.
class ChildEnemy1 : public Enemy
{
ChildEnemy1() : name("Enemy1") {}
};

Class creating another and returning the pointer. Is it a violation of SOLID principles

I am not an expert in SOLID principles, therefore got this question.
Does the following violate the SOLID principles? If yes, what would be the ideal solution? (Please check the highlighted code following the example)
class IUser
{
public:
virtual string GetName() = 0;
private:
string m_strName;
};
class CUser : public IUser
{
public:
CUser(string strEmail) : m_strEmail(strEmail) {}
virtual string GetName() {return m_strName;}
string m_strEmail;
};
class ISignIn
{
public:
virtual IUser* GetUser(string strEmail) = 0;
};
class CSignIn : public ISignIn
{
public:
virtual IUser* GetUser(string strEmail)
{
return new CUser(strEmail);
}
};
The code I am concerned about is:
return new CUser(strEmail);
Thanks everybody for answering this question!

Dynamic Polymorphism Error in code C++

#include <iostream>
#include <string>
using namespace std;
class Employee
{
public :
virtual int calculateSalary()= 0;
virtual string getName()=0;
virtual string getEngineer()=0; //error
virtual string getManager()=0; /error
virtual string getDirector()=0; /error
};
class Engineer: public Employee
{
protected:
string name;
int salary;
public:
Engineer(string n,int s):name(n),salary(s){ cout<<endl<<"Engineer Created"; }
~Engineer(){cout<<endl<<"engineer destroyed";}
int calculateSalary()
{
return salary * 2;
}
string getName()
{
return name;
}
string getEngineer()
{
return "Engineer";
}
};
class Manager:public Engineer
{
public:
Manager(string n,int s): Engineer(n,s) { cout<<endl<<"Manager Created"; }
~Manager(){cout<<endl<<"MANAGER destroyed";}
int calculateSalary()
{
return salary * 3;
}
string getName()
{
return name;
}
string getManager()
{
return "manager";
}
};
class Director:public Manager
{
public:
Director(string n,int s): Manager(n,s) { cout<<endl<<"Director Created"; }
~Director(){cout<<endl<<"Director destroyed";}
int calculateSalary()
{
return salary * 4;
}
string getName()
{
return name;
}
string getDirector()
{
return "director";
}
};
int main()
{
Engineer e1("rohit",20000),e2("soham",21000);
Manager m1("shyam",23000),m2("ram",23500);
Director d1("rahul",25000);
Employee *staff[] = {&e1,&e2,&m1,&m2,&d1};
for(int i=0;i<5;i++)
{
cout<<endl<<"Name : "<<staff[i]->getName() << "\t" << "Salary : " << staff[i]->calculateSalary();
}
cout<<endl<<staff[0]->getEngineer(); //error
cout<<endl<<staff[1]->getEngineer(); //error
cout<<endl<<staff[2]->getManager(); //error
cout<<endl<<staff[3]->getManager(); //error
cout<<endl<<staff[4]->getDirector(); //error
return 0;
}
/The lines with error are showing errors if i compile this code.
i want to know if it is possible to access the getEngineer(),getManager(),getDirector() via the staff pointer.
If yes, then how?
If not, then why?
and is there any alternative to access those functions keeping the data type of staff as it is(i.e Employee) ?/
All derived class from Employee must to implement all pure virtual methods, otherwise they cannot be instanced.
Why does this happen?
A derivative class inherits all methods (and member variables) from the base class.
In you case, base class has some pure virtual methods, and so the sub-classes (Engineer, Manager and Director) as well. A no-abstract class cannot have a pure virtual method, so in order to instantiate those classes, each of them should implement getEngineer() getManager() getDirector() methods.
What is the solution?
The problem in your case is a bad design decision.
The base class should represent a uniform interface for all derivative classes.
That's why, the base class Employee should not have method like getEngineer() which is a more specific information.
IMO, a better design decision (just looking at your code) could be:
class Employee {
public :
virtual int calculateSalary() = 0;
virtual string getName() = 0;
virtual string getTypeWork() = 0;
};
In that way (exploiting polymorphism property) each derivative class can correctly return a string representing its role job.
it is possible to access the getEngineer(),getManager(),getDirector() via the staff pointer. If yes, then how?
Yes, you can. However, as #Biagio Festa said you can't have pure virtual functions in your base class Employee without implementing them in your derived ones. So one solution could be having default implementations for those functions in your base class
class Employee
{
public :
virtual int calculateSalary()= 0;
virtual string getName()=0;
virtual string getEngineer() { return std::string(); }
virtual string getManager() { return std::string(); }
virtual string getDirector() { return std::string(); }
};
Then, you can override those functions in your derived classes only when needed like you did in your example.

VC++: Prevent duplicated member variable name declaration in derived class

I am trying to refactor and rewrite some parts of a legacy library. This library has base classes with same variable names repeatedly declared and used in derived classes (caused by copy/paste programming). For example I have:
class MyBaseClass
{
public:
int m_nVar;
protected:
virtual void MyFunc()
{
m_nVar++;
}
public:
MyBaseClass()
{
m_nVar = 1;
}
};
class MyDerivedClass : public MyBaseClass
{
public:
int m_nVar;
protected:
virtual void MyFunc()
{
m_nVar++;
}
public:
MyDerivedClass ()
{
m_nVar = 2;
}
};
This situation causes me problems because I need to move some functionality I need to a more general base class so that MyBaseClass can be derived from it.
class MyNewBaseClass
{
public:
int m_nVar;
protected:
virtual void MyFunc()
{
m_nVar++;
}
public:
MyNewBaseClass()
{
}
};
class MyBaseClass : public MyNewBaseClass
{
public:
MyBaseClass()
{
m_nVar = 1;
}
};
class MyDerivedClass : public MyBaseClass
{
public:
int m_nVar;//this causes me problems, I need to get notifications on occurrences of such situations
public:
MyDerivedClass ()
{
m_nVar = 2; //this assignments has no effect on MyNewBaseClass::m_nVar
}
};
After I make my modifications MyFunc() in a MyDerivedClass instance does not work as the original code (first run on original causes m_nVar = 3, but in my modified code it becomes m_nVar = 2).
I need some kind of compiler error or warning to notify me of all occurrences of such situations or any other solutions to accomplish what I need.
What do you suggest which works in Visual Studio (VC++)?

C++ multiple inheritance

Please don't question the really odd hierarchy of workers in this code here, I have no idea why anyone would want something like this, but I decided to give myself an exercise in Multiple Inheritance, just to be sure I fully understood it. So here's the result.
using namespace std;
class Employee
{
protected:
string name;
public:
string getname()
{
return name;
}
void setname(string name2)
{
name = name2;
}
Employee(string name2)
{
name = name2;
}
Employee(){}
};
class Manager : public Employee
{
public:
string getname()
{
return ("Manager" + name);
}
Manager(string name2) : Employee(name2){}
Manager() : Employee(){}
};
class Supervisor : public Manager,public Employee
{
public:
Supervisor(string name2) : Manager(name2) , Employee(name2){}
Supervisor() : Manager() , Employee(){}
string getname()
{
return ("Supervisor" + Employee::getname());
}
};
Hopefully you're understanding what I'm trying to do here. I'm getting something about an "ambiguous conversion between derived class 'Supervisor' and base class 'Employee.'" So what do I do?
Actually, the way you have defined Supervisor class, its object will have two subjects of type Employee, each coming from it base classes. That is causing problem.
The solution is to use virtual inheritance (assuming you need multiple inheritance) as:
class Manager : public virtual Employee
Hope you note the virtual keyword here. :-)
Everybody has already covered virtual inheritance, but I'd suggest reading the C++ FAQ as well.
http://www.parashift.com/c++-faq-lite/multiple-inheritance.html
You need a virtual inheritance in this case:
#include <iostream>
#include <string>
using namespace std;
class Employee
{
protected:
string name;
public:
string getname()
{
return name;
}
void setname(string name2)
{
name = name2;
}
Employee(string name2)
{
name = name2;
}
Employee(){}
};
class Manager : public virtual Employee
{
public:
string getname()
{
return ("Manager" + name);
}
Manager(string name2) : Employee(name2){}
Manager() : Employee(){}
};
class Supervisor : public Manager,public virtual Employee
{
public:
Supervisor(string name2) : Manager(name2) , Employee(name2){}
Supervisor() : Manager() , Employee(){}
string getname()
{
return ("Supervisor" + Employee::getname());
}
};
This problem is also known as Diamond inheritance problem:
http://en.wikipedia.org/wiki/Diamond_problem
Supervisor contains two objects of type Employee, the direct one and the one over Manager. It is ambiguous to call Employee methods on a Supervisor in consequence (which Employee should be called?). You might want to employ virtual multiple inheritance instead.