Passing variables to a constructor with multiple inheritance - c++

I am having problems passing up two pieces of data through my classes, ID and Name specificly. I understand that you cannot call the base class constructor up without going through the previous parent classes but I am struggiling to fiugure out why this is not working, do I need constructors all the way up or can I just add it on at the end of my class creation like the base class?
Thanks in advance.
class CEmployee
{
private:
char m_name[30];
char m_id[30];
//virtual float Pay() { return 0;}; // virtual function
virtual float Pay() = 0; // pure virtual function
public:
CEmployee(char name[], char id[])
{
strcpy_s(m_name, name);
strcpy_s(m_id, id);
}
CEmployee()
{
strcpy_s(m_name, "");
strcpy_s(m_id, "");
}
void PrintCheck()
{
cout << m_name << " " << Pay() << endl;
}
};
class CFulltimeEmployee : public CEmployee
{
protected:
static float m_benefitcost;
public:
CFulltimeEmployee()
{
}
CFulltimeEmployee(char name[], char id[]) : CEmployee (name, id)
{
m_benefitcost = 100;
}
};
float CFulltimeEmployee::m_benefitcost = 100;
class CHourlyFTEmployee : public CFulltimeEmployee
{
private:
float m_rate;
float m_hours;
public:
CHourlyFTEmployee()
{
}
CHourlyFTEmployee(const char name[], const char id[], float rate, float hours) : CFulltimeEmployee
(name, id)
{
m_rate = rate;
m_hours = hours;
}
float Pay()
{
return m_rate * m_hours - m_benefitcost;
}
};
Errors
Error (active) E0289 no instance of constructor "CFulltimeEmployee::CFulltimeEmployee" matches the argument list
Error C2664 'CFulltimeEmployee::CFulltimeEmployee(char [],char [])': cannot convert argument 1 from 'const char []' to 'char []' Project9

Writing a minimal reproducible example really isn't that hard; you remove whatever isn't needed while still demonstrating the problem. In this case, it might be:
class CEmployee
{
char m_name[30];
char m_id[30];
virtual float Pay() = 0; // pure virtual function
public:
CEmployee(char name[], char id[])
{
strcpy_s(m_name, name);
strcpy_s(m_id, id);
}
};
struct CFulltimeEmployee : public CEmployee
{
CFulltimeEmployee(char name[], char id[]) : CEmployee(name, id) { }
};
struct CHourlyFTEmployee : public CFulltimeEmployee
{
CHourlyFTEmployee(const char name[], const char id[]) : CFulltimeEmployee(name, id) { }
float Pay() override { return 0.0; }
};
In particular, notice that none of m_benefitcost, m_rate or m_hours are needed; nor is PrintCheck(). (class is private by default while struct is public; this also helps to reduce noise.)
Once you've done that, it's very easy to see the problem the compiler is complaining about
error C2664: 'CFulltimeEmployee::CFulltimeEmployee(char [],char [])': cannot convert argument 1 from 'const char []' to 'char []'
In CHourlyFTEmployee, you've written const char name[] (and const char id[]); but the base class (CFulltimeEmployee) is char name[]—no const. Data that is const can't "easily" be assigned to non-const data; the "fix" is straight-forward: remove the const:
CHourlyFTEmployee(char name[], char id[]) : CFulltimeEmployee(name, id) { }`
The sample still has other issues, but it sounds like you're stuck with the existing CEmployee base class.
An even better solution is to hide as much of the legacy CEmployee class as possible; maybe by introducing another class CEmployeeNew (or CEmployee2); that might look like:
struct CEmployeeNew : public CEmployee
{
CEmployeeNew(const std::string& name, const std::string& id) :
CEmployee(const_cast<char*>(name.c_str()), const_cast<char*>(id.c_str())) { }
};

Related

C++ OOP inheritance, why this code couts "Data"

Two classes: Data is parent and DerivedData is child. Why does cout output "Data"?
class Data {
protected:
int _value {};
public:
Data(int value) : _value{ value } { }
std::string getName() const {
return "Data";
}
int getValue() const {
return _value;
}
void setValue(const int i) {
_value = i;
}
};
class DerivedData: public Data {
public:
DerivedData(int value) : Data{ value } { }
std::string getName() const {
return "DerivedData";
}
int getValueDoubled() const {
return _value * 2;
}
};
DerivedData dd{ 5 };
Data d = dd;
Data& rd = dd;
cout << rd.getName() << endl;
This code will output "Data", but why?
You are not using virtual so it is kinda redefinition of the parent function which you think is polymorphsim but it is not.
When it execute this line of code Data& rd = dd; you had expected to be printed DerviedData but this did not happen because your function was not virtual, and base class do not know you are overriding the getName method in derived class.
So to fix this issue need to declare your function virtual:
virtual std::string getName() const { return "Data"; } //Data
And in DerivedData:
std::string getName() const override { return "DerivedData"; } //DerivedData
Now this will behave the way you'd expected.

C++ I have some seryous issues with inheritance when derived and base class have different types of parameters, like shown below:

Im a newbie in c++ and recently discovered classes;
I learned about constructors, overloading operators, the rule of three and right now i tried to learn inheritance.
I created 4 classes: 2 parents, 2 childs, but i occured some problems in class parent1
This is class parent1:
class parent1{
protected:
float slr;
int age;
char *name;
void set_new_name(char ch[10001]);
public:
parent1()
{
slr=0.0;
age=0;
name=NULL;
}
parent1(char ch[10001], float sl, int ag)
{
slr=sl;
age=ag;
set_new_name(ch);
}
parent1(const parent1 &p1)
{
char temp[10001];
strcpy(temp,p1.name);
if(name != NULL)
delete[] name;
set_new_name(temp);
slr=p1.slr;
age=p1.age;
}
parent1 &operator=(const parent1 &p1)
{
/// same lines as in copy constructor above
return *this;
}
char* get_name() const;
void print1();
~parent1()
{
delete[] name;
}
};
This is his child class, child1:
class child1 : public parent1{
protected:
int id;
void set_id(int j);
public:
child1(): parent1()
{
set_id(0);
}
child1(char ch[10001],float sl, int ag, int j): parent1(ch,sl,ag)
{
set_id(j);
}
child1(const child1 &p2): parent1(p2)
{
set_id(p2.get_id());
}
child1 &operator=(const child1 &p2)
{
set_id(p2.get_id());
parent1::operator=(p2);
}
int get_id() const;
void print2();
};
There is class parent 2:
class parent2{
protected:
char *name1;
char *name2;
void set_new_name1(char ch1[10001]);
void set_new_name2(char ch2[14]);
public:
parent2()
{
name1=NULL;
name2=NULL;
}
parent2(char ch1[10001], char ch2[14])
{
set_new_name1(ch1);
set_new_name2(ch2);
}
parent2(const parent2 &p3)
{
char temp2[10001];
strcpy(temp2,p3.name1);
if(name1 !=NULL)
delete[] name1;
set_new_name1(temp2);
/// .. . same lines as above, this time for name2 and p3.name2
}
parent2 &operator=(const parent2 &p3)
{
/// .. same lines as in copy constructor above
return *this;
}
char* get_name1() const;
char* get_name2() const;
void print3();
~parent2()
{
delete[] name1;
delete[] name2;
}
};
And there is his child, child 2:
class child2: public parent2{
protected:
char *job;
void set_new_job(char ch3[15]);
public:
child2(): parent2()
{
job=NULL;
}
child2(char ch1[10001], char ch2[10001],char ch3[11]): parent2(ch1,ch2)
{
set_new_job(ch3);
}
child2(const child2 &p4): parent2(p4)
{
char temp6[11];
strcpy(temp6, p4.job);
if(job != NULL)
delete[] job;
set_new_job(temp6);
}
child2 &operator=(const child2 &p4)
{
/// same lines as in copy constructor
parent2::operator=(p4);
}
char* get_job() const;
void print4();
~child2()
{
delete[] job;
}
};
As u can see up here, class parent1 have 3 types of parameters ( one float, one int and one char*).
Nonte: set_ functions works ok, get_functions just return class parametes (also works ok) , print functions just print classes parameters ( ex: cout << name1; also works fine)
The problem is that this code refuse to work when i create the objects in main.
First i thought it is operator= being overloaded to many times, bit it turned out to be the float parameter from parent1
There is the main:
char ch[10001]="my name", ch1[10001]="my name 1", ch2[14]="my name 2", ch3[11]="some code";
int ag=10;
float sl=10.1;
parent1 o1;
o1=parent1(ch,sl,ag);
o1.print1();
parent1 o2(o1);
o2.print1();
child1 o3;
o3=child1(ch,sl,ag,3);
o3.print2();
child1 o4;
o4=child1(ch,sl,ag,6);
o4.print2();
o4=o3;
o4.print2();
parent2 o5;
o5=parent2(ch1,ch2);
o5.print3();
child2 o6(ch1,ch2,ch3);
o6.print4();
The only things that seems to make it run are:
deleting the float parameter from parent1;
deleting the last class ; (i really don't know why the last class affect the program)
creating the last object like this : child2 o6(ch1,ch2,ch3); , which is frustrating because it should work like the others;
I know the code i sheared is very long, but Please , Help me to understand what i need to do to solve this stupid bug !
I see at least 3 issues in the code that will lead to a crash/undefined behavior.
First:
parent1(const parent1 &p1)
{
char temp[10001];
strcpy(temp,p1.name);
if(name != NULL) // name isn't initialized yet,
delete[] name; // these 2 lines shouldn't be here
set_new_name(temp);
slr=p1.slr;
age=p1.age;
}
Second: (these ones are reported by the compiler when warnings are enabled)
child1 &operator=(const child1 &p2)
{
set_id(p2.get_id());
parent1::operator=(p2);
return *this; // this line is missing
}
Third:
child2 &operator=(const child2 &p4)
{
char temp7[11];
strcpy(temp7, p4.job);
if(job != NULL)
delete[] job;
set_new_job(temp7);
parent2::operator=(p4);
return *this; // this line is missing
}
The return statement is not "inherited". Each function that's supposed to return something must do so.
With these changes the code runs:
my name
my name
3
6
3
my name 1
my name 2
some code
(Live demo)
Some additional improvement notes:
An array like char ch[10001] can't really be a function argument in C++. When it's used as an argument it silently decays to char *. So you might as well replace all char ch[10001] with const char* ch (and better yet, std::string), to avoid confusion.
Also, there's no point in allocating a temp array. You can just directly do set_new_name(p1.name):
parent1(const parent1 &p1)
{
set_new_name(p1.name);
slr=p1.slr;
age=p1.age;
}
It would be prudent to invest some time in getting familiar with a Debugger. It's all but impossible to make a working application without debugging it. And enable compiler warnings. With GCC use -Wall -Wextra, with MSVC - /W4.
Here's an example of the code using std::string. Thanks to std::string we can follow the rule of 0:
class parent1 {
protected:
float slr = 0;
int age = 0;
string name;
void set_new_name(string const &ch) { name = ch; }
public:
parent1() {}
parent1(string const &name, float slr, int age)
: slr(slr), age(age), name(name) {}
string const &get_name() const { return name; }
void print1();
};
void parent1::print1() { cout << get_name() << '\n'; }
class child1 : public parent1 {
protected:
int id = 0;
void set_id(int j) { id = j; }
public:
child1() : parent1() {}
child1(string const &name, float sl, int ag, int j)
: parent1(name, sl, ag), id(j) {}
int get_id() const { return id; }
void print2();
};
void child1::print2() { cout << get_id() << '\n'; }
class parent2 {
protected:
string name1;
string name2;
void set_new_name1(string const &ch) { name1 = ch; }
void set_new_name2(string const &ch) { name2 = ch; }
public:
parent2() {}
parent2(string const &name1, string const &name2)
: name1(name1), name2(name2) {}
string const &get_name1() const { return name1; }
string const &get_name2() const { return name2; }
void print3();
};
void parent2::print3() {
cout << get_name1() << '\n';
cout << get_name2() << '\n';
}
class child2 : public parent2 {
protected:
string job;
void set_new_job(string const &ch) { job = ch; }
public:
child2() : parent2() {}
child2(string const &name1, string const &name2, string const &job)
: parent2(name1, name2), job(job) {}
string const &get_job() const { return job; }
void print4();
};
void child2::print4() { cout << get_job() << '\n'; }
And this works equally well.

pure virtual method called terminate called without an active exception When the function does, it returns

Hi I'm doing a function to find a transport by number but I'm experiencing an error I don't know why.
I have to abstract base class "Transport".
class Transport
{
protected:
int transportNumber;
char transportName[20];
char company[20];
struct tm dateOfMaking;
double speed;
char propertyType[20];
char transportType[20];
public:
Transport();
Transport(int,char*, char*, struct tm, double, char*, char*);
~Transport();
virtual char* GetName() = 0;
virtual bool Warning(double);
virtual void Print() = 0;
virtual void Save() = 0;
virtual int GetPassengerNumber();
virtual double GetEmptyWeight();
char * GetTransportType() { return transportType; }
int GetTransportNumber() { return transportNumber;}
};
This class inherits from Transport.
class Aerial : public Transport
{
protected:
int engineNumber;
double length;
public:
Aerial() {}
Aerial(int, char*, char*, struct tm, double, char*, char*, int, double);
~Aerial();
};
I have this class that inherits from class Aerial.
class PassengerPlane : public Aerial
{
private:
int seatNumber;
double Bagswieght;
public:
PassengerPlane() {}
PassengerPlane(int, char*, char*, struct tm, double, char*, char*, int, double, int,double);
~PassengerPlane();
char* GetName();
bool Warning(double);
int GetPassengerNumber() { return seatNumber; }
void Save();
void Print();
};
With the ProgrammeManagement::TransporSearchByNumber(int TN) function returning the Transport* value You have stored and searched for objects in the file in this function as follows:
Transport* ProgrammeManagement::TransporSearchByNumber(int TN)
{
char num;
int x = 1;
PassengerPlane e;
Transport *T;
fstream file(Type,ios::in);
fstream fil(TransportFilePath,ios::in);
while(file.get(num))
{
if( num == '1')
{
fil.read((char*)&e,sizeof(PassengerPlane));
T = &e;
if( TN == T->GetTransportNumber()){
x = 0;
return T;
}
}
}
if(x){
cout << "Not found";
}
file.close();
fil.close();
}
In my main I do the following:
Transport*s;
s = ProgrammeManagement::TransporSearchByNumber(2);
s->Print();
but when I call the Print() function on Transport, I get the following error (on runtime, it compiles):
pure virtual method called
terminate called without an active exception
Any help how to solve this issue.
Thank you very much in advance!

Virtual Class and Inheritance

I get a compile error "cannot convert 'Chips' to 'GroceryItem' and I'm having trouble figuring out how to actually convert something to a virtual class object. Teacher provided a 'GroceryCart' class that adds GroceryItems to the cart in 'main' and prints the cart out.
class GroceryItem {
public:
virtual ~GroceryItem();
virtual float GetPrice() = 0;
virtual char* GetDescription() = 0;
virtual float GetWeight() = 0;
};
#include "GroceryItem.h"
class Chips : public GroceryItem {
public:
Chips();
~Chips();
float GetPrice();
char* GetDescription();
float GetWeight();
private:
float price;
char* itemName;
float weight;
};
#include "GroceryItem.h"
#include "Chips.h"
Chips::Chips() {
price = 0.75;
itemName = new char[5];
itemName = "Chips";
weight = 1.0;
}
Chips::~Chips() {
delete this;
}
float Chips::GetPrice() {
return price;
}
char* Chips::GetDescription() {
return itemName;
}
float Chips::GetWeight() {
return weight;
}
int main(int argc, const char * argv[])
{
GroceryCart c;
c.AddItemToCart(new Chips);
std::cout << c;
return 0;
}
void GroceryCart::AddItemToCart(GroceryItem *i)
{
items.push_back(i);
}
provide full error log, check that container parameterized with pointer to GroceryItem (<GroceryItem*>)
As someone pointed out
delete[] itemName; //destructor
but you also have to define non-trivial copy-constructor/operator=, so it's better to replace char* with std::string, also need defined destructor for base abstract class even it's pure virtual.

object of abstract type "NumericQuestion" is not allowed in c++

Also, what does this code doing exactly?
const int MAX_QUESTIONS = 100;
Question* questions[MAX_QUESTIONS];
questions[numQuestions++] = createQuestion("How many degrees are there in a full circle?", 360);
and
Question* createQuestion(const char question[], const double answer)
{
NumericQuestion* nq = new NumericQuestion(question, answer);
return nq;
}
Thanks a lot. I really need your help to explain to me
Edit: Here is the declaration for Question
class Question
{
char *q;
protected:
void writeQuestion(ostream& ostr) const;
public:
Question(const char question[])
{
int n = strlen(question);
q = new char[n];
strcpy(q, question);
cout << q;
}
void askQuestion() const;
virtual void getAnswer();
virtual bool isCorrect() const=0;
};
Edit: Declaration for NumericQuestion
class NumericQuestion : public Question
{
double ans, geta;
public:
NumericQuestion(const char question[], const double answer): Question(question)
{
ans = answer;
getAnswer();
}
void getAnswer()
{
cout << "Answer: ";
cin >> geta;
isCorrect();
}
bool isCorrect()
{
return ((geta==ans)? true : false);
}
};
Stackoverflow doesn't allow me to post so much code
You need to declare isCorrect() as const in NumericQuestion:
bool isCorrect() const // <--- add const keyword here
The reason is because const is part of the method signature, like its name and parameters. isCorrect() const is a different method than a function named isCorrect() that isn't const.
When you see a virtual method with =0, that means the method is "pure virtual". The base class doesn't normally specify an implementation, but before any derived class can be instantiated, an implementation has to be defined.