I have an abstract class, that has two variables. I want to instantiate those variables through the constructor.
Then I want to instantiate those variables from the child classes constructors, but it giving me a casting error?
#ifndef Employee_Interface_H
#define Employee_Interface_H
#include <iostream>
using namespace std;
class Employee {
private:
double salary = 0;
double sales = 0;
double bonus = 0;
public:
Employee(double empSalary, double empSales) {
salary = empSalary;
sales = empSales;
}
void virtual calculateBonus() = 0;
};
class Staff : public Employee {
public:
Staff(double empSalary, double empSales) {
Employee(empSalary,empSales);
}
void calculateBonus() {
//20% of salary
}
};
#endif
`
Instead of this:
Staff(double empSalary, double empSales) {
Employee(empSalary,empSales);
}
Use this instead:
Staff(double empSalary, double empSales) :
Employee(empSalary, empSales)
{
}
You have to put the base class constructor call in the derived class constructor's member-initialization-list - after the : marker, but before the constructor's body definition.
Related
Is there a way to make it so that each of Special and normal employees each have their own unique counter and that the function in the base class uses the class specific counter if the function is called from NormalEmp or SpecialEmp object
class Employee {
public:
static int count ;
Employee(){ count++;}
void foo(){
if(count > 50)
//do 1,2,3
}
};
int Employee::count = 0;
class NormalEmp :public Employee
{
};
class SpecialEmp :public Employee
{
};
If I understand you correctly you could retrieve count via a (pure) virtual getter:
class Employee {
public:
virtual int getCount() const = 0;
void foo(){
auto count = this->getCount();
// ...
}
};
class NormalEmp :public Employee
{
public:
static int count;
int getCount() const override {
return NormalEmp::count;
}
};
SpecialEmp would look the same, it's just the basic idea.
#include <string>
#include <iostream>
using namespace std;
class Surgery
{
public:
Surgery();
int getPrice();
string getType();
protected:
int price;
string type;
};
Surgery::Surgery()
{
price = 0;
type = "";
}
int Surgery::getPrice()
{
return price;
}
string Surgery::getType()
{
return type;
}
class Neurosurgery :public Surgery
{
private:
string type = "Neurosurgery";
int price = 23000;
};
class Plastic :public Surgery
{
private:
string type = "Plastic";
int price = 15000;
};
class Trauma :public Surgery
{
private:
string type = "Trauma";
int price = 5000;
};
class Endocrine :public Surgery
{
private:
string type = "Endocrine";
int price = 20000;
};
class Ophthalmological :public Surgery
{
public:
Ophthalmological();
private:
string type;
int price;
};
Ophthalmological::Ophthalmological():Surgery()
{
type = "Ophthalmological";
price = 10000;
}
int main()
{
Ophthalmological var1;
cout << var1.getPrice() << endl;
return 0;
}
When i run this code i expected to see 10000
Instead i see 0
I made it really simple to avoid any mistake with const, singlone default constructors.
First Surgery constructor gets executed after Neurosurgery.
Neurosurgery constructor should overwrite values that default Surgery constructor made.
Am i using c++11 in wrong style
This is because you are declaring tow times the variable price and type and, and when you are invoking cout << var1.getPrice() << endl; it takes the variable of Surgery. You should do:
class Surgery
{
public:
Surgery();
int getPrice();
string getType();
protected:
int price;
string type;
};
class Ophthalmological :public Surgery
{
public:
Ophthalmological();
private:
//string type; //It has been declared into Survey
//int price; //It has been declared into Survey
};
I ran your code with this modification and return the value of the unique price variable.
This is caused by the fact that it is not virtual, and there are multiple variables with the same name. So you get value from the base class Surgery. The other classes also define the variables with the same name. I think the simplest solution is this: Keep the protected variables in the base class and remove those variables from the subclasses.
I want provide a class with a member function that will initialize the all member of class separately.
e.g.
#include <iostream>
using namespace std;
int x = 10;
class my{
public:
my():init{}
int &i;
void init()
{
i = x;
}
};
int main()
{
my m;
return 0;
}
I know if I can use "class my : i(init())" will work, but I have some special purpose to intialize like above.
However in above example, I'm getting following error:
class ‘my’ does not have any field named ‘initMy’.
How to resolve this?
If you are trying to write a constructor for class my, then it must be named with the class name. The following will work assuming that initMy is the name of another class that you are trying to subclass.
class my : initMy
{
public:
int i;
my() {
i = 10;
}
};
You might try to pre-initialize all the fields, then calling the initializing function inside the constructor:
class my {
public:
int i;
void initMy() {
i = 10;
}
my() : i(0) { initMy(); };
};
You could also (in C++11) define a bizarre signature for a private constructor, and delegate a constructor to it
class my {
private:
void initMy () { i=10; };
enum privateen {privatev};
my(enum privateen) : i(0) { initMy(); };
public:
my() : my(privatev) {};
int i;
};
Actually, I believe that your initialization should be in a constructor, not in some other function.
Few things to clarify here.
Member initialization list is for initialize members (mostly same purpose of the constructor).In initialize list nothing to do with member functions. in this example age(newAge) is not a function. It is initializing age variable.
class Man{
private:
int age;
string name;
public:
Man(int newAge):age(newAge),name("Jhon"){}
};`
You can use constructor to initialize the members of the class.
class Man{
private:
int age;
string name;
public:
Man(int newAge)
{
age = newAge;
name = "Jhone";
}
};
Alternatively you can use a init method to do initialization, if you have some issue to use constructor.
class Man{
private:
int age;
string name;
public:
Man(){}
init(int newAge, string newName)
{
age = newAge;
name = newName;
}
};
If you need to set the value of only one member in a class, you have to use a setter method
class Man{
private:
int age;
string name;
public:
Man(){}
setAge(newAge)
{
age = newAge;
}
setName(newName)
{
name = newNAme
}
};
edit:
class Man{
private:
int age;
string name;
public:
Man(initAge, initName)
{
setValues(initAge, initName);
}
setValues(newAge, newName)
{
age = newAge;
name = newName;
}
};
int main()
{
Man goodMan(34,"Jhon");
goodMan.setValues(45,"Kevin");
}
I have the base class Manager and the derived class Worker, the inheritance seem to work properly - I've created a new object of the derived class using it's default constructor and i can output properly.
but now I want to make an overloaded constructor for the derived class (Worker) and there seem to be a compilation error, I tired to look for an answer but I didn't found one.
why the compiles says that Worker doesn't have id, name and salary fields? I've created a derived class by the book and created ctors for it.
Manager header:
#include <string>
#ifndef MANAGER_H
#define MANAGER_H
class Manager
{
public:
Manager (); //ctor
Manager (std::string, std::string, float, int); //overloaded ctor
friend void display (Manager&); //friend function is declared
~Manager (); //dtor
protected:
std::string id;
std::string name;
float salary;
private:
int clearance;
};
Manager cpp:
#include <iostream>
#include "Manager.h"
#include "Worker.h"
Manager::Manager() //default ctor
{
id = "M000000";
name = "blank";
salary = 0;
clearance = 0;
}
Manager::Manager(std::string t_id, std::string t_name, float wage, int num): id (t_id), name (t_name), salary(wage), clearance (num)
{
//overloaded ctor
}
Manager::~Manager()
{
//dtor
}
Worker header:
#include <string>
#ifndef Worker_H
#define Worker_H
class Worker: public Manager
{
public:
Worker();
Worker (std::string, std::string, float, int);
~Worker();
friend void display (Worker&); //friend function is declared
protected:
int projects;
private:
};
#endif // Worker_H
Worker cpp:
#include <iostream>
#include "Manager.h"
#include "Worker.h"
Worker::Worker() //default ctor
{
id = "w000000";
name = " - ";
salary = 0;
projects = 0;
}
Worker::Worker(std::string t_id, std::string t_name, float wage, int num) : id (t_id), name (t_name), salary (wage), projects (num);
{
//ctor
}
Worker::~Worker()
{
//dtor
}
Worker::Worker(std::string t_id, std::string t_name, float wage, int num) : id (t_id), name (t_name), salary (wage), projects (num)
{
//ctor
}
here you initialize the members id,name, salary and clearance defined in base class. you need to pass it to the base class constructor for initialization. you cannot initialize them directly.
id, name and clearance are protected so you can access them in derived class but you cannot initialize them directly using initialization list. either you can initialize inside the constructor or make a call to base constructor in initialization list.
Worker::Worker(std::string t_id, std::string t_name, float wage, int num):Manager(t_id,t_name,wage,0), projects (num)
{
//ctor
}
Derived classes don't see private members of their base class. You have to delegate the constructor.
Your Worker constructors should be like:
Worker::Worker() : Manager("w000000", " - ", 0, 0) {}
Worker::Worker(std::string t_id, std::string t_name, float wage, int num) :
Manager(t_id, t_name, wage, num)
{
}
I have recently transitioned from Java to C++, and I am having some difficulties working out how class inheritance works exactly. Currently, I have the class Weapon and the class Minigun. Minigun inherits the class Weapon, which means it should have the methods and variables that Weapon defines. My issue is that I have a private constant static int inside Weapon called rate, and a public method that returns an integer called getRate(). getRate() simply returns the rate variable as defined in the class. When Minigun extends Weapon, and I set the rate inside Minigun, the getRate() method still returns the constant from the Weapon class, even though it is being called on the Minigun class. I thought it would act like Java, and the intherited method would use the modified variable inside Minigun. Currently I have to do the following;
Weapon.h
#ifndef __WEAPON__
#define __WEAPON__
class Weapon
{
public:
virtual int getRate()
{
return rate;
}
private:
const static int rate = 0;
};
#endif
Minigun.h
#include "Weapon.h"
#ifndef __WEAPON_MINIGUN__
#define __WEAPON_MINIGUN__
class Minigun: public Weapon
{
public:
int getRate(); // I have to define this here, and create it inside Minigun.cpp
private:
const static int rate = 30;
};
#endif
Minigun.cpp
#include "Minigun.h"
int Minigun::getRate() // Is there a way so I do not need to type this out for every class that extends Weapon?
{
return rate;
}
Weapon instances would return a rate of Weapon::rate through getRate() and Minigun instances would return a rate of Minigun::rate.
Because the method getRate() is virtual a Weapon pointer or reference to a Minigun instance would return a rate of Minigun::rate.
If only the rate variable changes in the derived classes, a template class would require less coding than the dynamic polymorphic version. The template version would look like:
template<int Rate = 0>
class Weapon
{
public:
int getRate() // no need for virtual anymore
{
return rate;
}
private:
const static int rate = Rate;
};
class Minigun: public Weapon<30> {};
Don't have it be static. For example:
#include <iostream>
class Weapon {
public:
Weapon();
virtual int Rate();
virtual void Rate(int r);
protected:
int rate;
};
Weapon::Weapon() {
rate = 10;
}
class Minigun : public Weapon {
public:
Minigun();
};
Minigun::Minigun() {
rate = 30;
}
int Weapon::Rate() {
return rate;
}
void Weapon::Rate(int r) {
rate = r;
}
int main() {
Minigun ThisGun;
Weapon AnyGun;
std::cout << ThisGun.Rate() << std::endl;
std::cout << AnyGun.Rate() << std::endl;
AnyGun.Rate(15);
std::cout << AnyGun.Rate() << std::endl;
return 0;
}
We declare a protected int in the base class. This means any derived class that inherits the base class will have that variable as well. You only declare a variable static if you want only one instance of that variable shared for all instances of that object.
Base constructors will get called before the derived constructor. You can reset default values in your derived constructor for objects of that specific type. Public functions will call the most derived virtual function. In this case, we want Minigun to behave the same for our rate functions so we simple do not implement any function for Minigun so the Weapon functions are called instead.
output is:
30
10
15