This question already has answers here:
What is this weird colon-member (" : ") syntax in the constructor?
(14 answers)
Closed 6 years ago.
I know that it can be a stupid but I even don't know how to name this question. I'm non native English. I learn C++ from a book and there is a program which shows name and pay rate of employee (base class) and Manager (derived class) with added bool variable salaried. Here is the source code:
//base class
class Employee {
private:
string name;
double pay;
public:
Employee() {
name = "";
pay = 0;
}
Employee(string empName, double payRate) {
name = empName;
pay = payRate;
}
string getName() const {
return name;
}
void setName(string empName) {
name = empName;
}
double getPay() const {
return pay;
}
void setPay(double payRate) {
pay = payRate;
}
string toString() {
stringstream stm;
stm << name << ": " << pay;
return stm.str();
}
};
//derived class
class Manager : public Employee {
private:
bool salaried;
public:
Manager(string name, double payRate, bool isSalaried)
:Employee(name, payRate)
{
salaried = isSalaried;
}
bool getSalaried() {
return salaried;
}
};
int main()
{
Employee emp1("Mary Smith", 15.00);
cout << "Employee name: " << emp1.getName() << endl;
cout << "Employee pay rate: " << emp1.getPay() << endl;
Manager emp2("Bob Brown", 1500, true);
cout << "Employee name: " << emp2.getName() << endl;
cout << "Employee pay rate: " << emp2.getPay() << endl;
cout << "Is Salaried: " << emp2.getSalaried() << endl;
return 0;
}
Can someone explain me why this part
:Employee(name, payRate)
must be added to code to work properly?
The part
:Employee(name, payRate)
you mention is used to call the constructor
Employee(string empName, double payRate)
of the base class Employee before executing the body of the constructor
Manager(string name, double payRate, bool isSalaried)
of the derived class Manager.
It calls the base class's (Employee) constructor and passes the name and payRate to it because they are members of Employee.
:Employee(name, payRate)
is the initialisation of the base class that class Manager inherits.
In fact without this line the code should compile fine(because you have a default constructor for Employee), but the fields inherited from Employee will not get properly initialized in emp2. What this portion of the code does is to call the constructor of Employee to initialize the fields inherited from that class.
What come after the colon on the constructor called initialization list and in your case it just initiate the base class with the suitable constructor
The code can work properly even without the constructor(i.e..you can use the default constructor to accept the variables and implement two methods for filling the name and pay.)
class Employee {
private:
string name;
string temp_name;
double temp_pay;
double pay;
public:
Employee() {
name = temp_name;
pay = temp_pay;
}
void getTempname(string tem){temp_name = tem;}
void getTemppay(double py){ temp_pay = pay;}
};
Related
Entry point is int main() so I try summon pwr.GetSalary to cout outside string "Salary" and double value, however program does not print out anything.
So it is base class.
class Employee
{
public:
std::string FirstName;
std::string LastName;
std::string Patronymic;
double Salary;
Employee() {};
explicit Employee(std::string FirstName, std::string LastName,
std::string Patronymic, double Salary)
: FirstName(FirstName), LastName(LastName),
Patronymic(Patronymic), Salary(Salary) {}
bool operator==(Employee other) const
{
if (this->FirstName == other.FirstName &&
this->LastName == other.LastName &&
this->Patronymic == other.Patronymic)
return true;
else
return false;
}
};
An daughter class that inherits base class... Here is wonderful method that shall count a salary and print it out...
class Papersworker : public Employee
{
private:
std::string FirstName;
std::string LastName;
std::string Patronymic;
double Salary;
public:
Papersworker() {};
using Employee::Employee;
const std::string Job = "Papersworker";
std::map<std::string, double> Coefficient =
{
{"Director", 4.2},
{"Papersworker", 1.2},
{"Guardian", 1.5},
{"Programmer", 2.5}
};
void ChangeCoefficient(std::string Job, double NewCoefficient)
{
Coefficient[Job] = NewCoefficient;
}
void ChangeNameSalary(std::string FirstName, std::string LastName, std::string Patronymic, double Salary)
{
this->FirstName = FirstName;
this->LastName = LastName;
this->Patronymic = Patronymic;
this->Salary = Salary;
}
void PrintPapersworker()
{
std::cout << "First name\t" << "Lastname\t" << "Patronymic\t" << "Salary\n" << this->FirstName << "\t\t" << this->LastName << "\t" << this->Patronymic << "\t" << this->Salary << "\n" << std::flush;
for (const auto& i : this->Coefficient)
{
std::cout << i.first << " = " << i.second << ";\t" << std::flush;
}
std::cout << "\n------------------------------------------------------------\n" << std::flush;
}
double GetSalary(double Salary, std::string Job)
{
return Salary * this->Coefficient[Job];
}
};
Wonderful int main()'s part.
int main()
{
Papersworker pwr;
double sr = 0.0;
std::cout << "\nEnter director's salary\t" << std::flush; std::cin >> sr;
std::cout << "\nSalary\t" << pwr.GetSalary(sr, "Director");
return 0;
}
If you see a some bad and need optimization don't mind to reply. ._. I do not understand what is going on there in matter of classes building tricks. https://pastebin.com/p7HXaX80
P. S. My homework forces to use private FirstName,LastName,Patronymic,salary...
P. S. S. However, I use Visual Studio 2022 Preview with newest C++ nowadays.
https://imgur.com/a/N8cDK3n
program does not print out anything
Your program(pastebin link you gave) compiles successfully and prints continuously if you change _getch() to getch() as can be seen here. But for some reason it goes on forever. Since the link that you gave have around 500 lines of code i didn't take a look as to why the condition is not breaking(or if the program has any undefined behavior). Maybe you can narrow down the problem and edit your question again.
Your code will not compile as sr variable is not defined.
Define double sr; before using it in main()'s statement std::cin >> sr; and (at least) the program will compile and interact with the user.
int main() {
Papersworker pwr;
std::cout << "\nEnter director's salary\t" << std::flush;
double sr; // <- your missed variable
std::cin >> sr;
std::cout << "\nSalary\t" << pwr.GetSalary(sr, "Director");
}
Program's prints with input 10:
Enter director's salary 10
Salary 42
All of the private members of Papersworker shadow the public members from Employee
class Papersworker : public Employee {
private:
std::string FirstName;
std::string LastName;
std::string Patronymic;
double Salary;
// ...
};
Try this: Compiler Explorer (Untested ’cause I’m in a rush right now, I’ll look at it when I come back)
Also, be careful with std::map::operator []
i am trying to make a payroll system hierarchy and my base class of all is a abstract class and all the other classes inherited are concrete classes (classes that can be instantiated).. i have a pure virtual function earning() in my base class abstract base class employee.. the proper functionality of earning is provided in the derived classes depending on the type of employee whose earning is being calculated. I also have a virtual function in the abstract base class that is display information which is overridden in all the derived classes.
The class hierarchy goes like this
class employee;
class commissionEmployee : public employee;
class salariedEmployee : public employee;
class basePlusCommissionEmployee : public employee
the commission employee's overridden pure virtual function earning adds up the gross sales of the employee in a week with the commission rate and should return a double.
the salaried employee's overridden earning function only returns the salary that is earned by the employee as his/her salary is the only earning.
the basePlusCommissionEmployee means that a employee who has both things being added up in his/her earning function that is the salary of that employee and the commission that employee will earn from the sales he/she makes..
the problem that i a facing is that when i use a base class pointer to point at a derived class's object.. the dynamic polymorphism does get implemented but in the displayInformation function that alse overridden in each class, i do not get the total information.. it does not displays the name of the employee nor his/her earning.
i have also posted an image that shows the output of the overridden displayInformation function of the salaried employee class.. other than name and social security number the only additional input salaried employee class asks for is the salary of that employee..
#include <iostream>
#include <cstdlib>
using namespace std;
class employee
{
private:
string name;
string socialSecurityNumber;
public:
void setName(string);
string getName();
void setSSN(string);
string getSSN();
virtual double earnings() = 0;
virtual void displayInformation();
};
void employee::setName(string argName)
{
name = argName;
}
string employee::getName()
{
return name;
}
void employee::setSSN(string argSSN)
{
socialSecurityNumber = argSSN;
}
string employee::getSSN()
{
return socialSecurityNumber;
}
void employee::displayInformation()
{
cout <<"name: " <<getName()
<<"Social security number: " <<getSSN();
}
class salariedEmployee : public employee
{
private:
double salary;
public:
void setSalary(double);
double getSalary();
virtual double earnings();
virtual void displayInformation();
};
void salariedEmployee::setSalary(double argSalary)
{
salary = argSalary;
}
double salariedEmployee::getSalary()
{
return salary;
}
double salariedEmployee::earnings()
{
//we will only return salary because that is the only earning of a salaried employee
return salary;
}
void salariedEmployee::displayInformation()
{
employee::displayInformation();
cout <<"weekly salary: " <<getSalary();
}
class commissionEmployee : public employee
{
private:
double commissionRate;
double grossSales;
public:
void setCommission(double);
double getCommission();
void setGrossSales(double);
double getGrossSales();
virtual double earnings();
virtual void displayInformation();
};
void commissionEmployee::setCommission(double argCommission)
{
commissionRate = argCommission;
}
double commissionEmployee::getCommission()
{
return commissionRate;
}
void commissionEmployee::setGrossSales(double argSales)
{
grossSales = argSales;
}
double commissionEmployee::getGrossSales()
{
return grossSales;
}
double commissionEmployee::earnings()
{
return (commissionRate * grossSales);
}
void commissionEmployee::displayInformation()
{
employee::displayInformation();
cout <<"\ncommission rate: " << getCommission()
<<"\nweekly sales: " <<getGrossSales();
}
class basePlusCommissionEmployee : public commissionEmployee
{
private:
double salary;
public:
void setSalary(double);
double getSalary();
virtual double earnings();
virtual void displayInformation();
};
void basePlusCommissionEmployee::setSalary(double argSalary)
{
salary = argSalary;
}
double basePlusCommissionEmployee::getSalary()
{
return salary;
}
double basePlusCommissionEmployee::earnings()
{
return (getSalary() + commissionEmployee::earnings());
}
void basePlusCommissionEmployee::displayInformation()
{
employee::displayInformation();
commissionEmployee::displayInformation();
cout <<"salay: " <<salary;
cout <<endl;
}
int main()
{
int choice;
double salary;
string name, SSN;
cout <<"choose\n1)salaried employee\n2)commission employee\n3)base plus salaried
employee\nenter: ";
cin >> choice;
cout <<"enter name: ";
cin >> name;
cout <<"enter SSN: ";
cin >>SSN;
if(choice == 1)
{
employee *pointerObj = new salariedEmployee;
salariedEmployee obj;
obj.setName(name);
obj.setSSN(SSN);
cout <<"enter weekly salary: ";
cin >> salary;
obj.setSalary(salary);
system("cls");
cout <<"total earning of this employee: " <<pointerObj->earnings();
cout <<endl;
pointerObj->displayInformation();
}
}
You have two distinct and different objects...
First you have the object pointed to by pointerObj, and the only thing you do with that object is to call its displayInformation function.
Then you have the obj object, which is where you set all values.
If you want to print all the data you set for obj then you need to call displayInformation on obj instead:
obj.displayInformation();
Otherwise you should set all the information on the object pointed to be pointerObj and don't have the variable obj at all.
Or a possible third solution:
employee *pointerObj = &obj;
I have a homework task with a given main.cpp code which is not allowed to be changed. According to that main.cpp and simple input and output(which is down below) example I must to finish the program.
My tries are: I'm trying to create 4 classes, class Person; class Worker; class Student; class InService; in my main function through instantiating an object of InService class I pass 4 parameters (name, sex, studentNo, workerNo); and with help of pointer of type of Base class, have the desired output. The error it shows is:
[Error] no unique final overrider for 'virtual std::string Person::getName()' in 'InService'
[Error] no unique final overrider for 'virtual int Person::getSex()' in 'InService'
I've tried to use virtual inheritance for that, but I can't really figure out how to solve this problem. I did some research on virtual inheritance, and referenced to other experts answers, but still getting confused with whole OOP stuff.
//Inservice.h
#include<string>
using namespace std;
class Person{
public:
Person();
~Person();
string name;
int sex;
virtual string getName() = 0;
virtual int getSex() = 0;
};
///////////////////////////////////////////////////
class Student:virtual public Person{
public:
Student();
~Student();
string sno;
virtual string getName() {
return name;
}
virtual int getSex(){
return sex;
}
string getSno(){
return sno;
}
};
//////////////////////////////////////////////////
class Worker:virtual public Person{
public:
Worker();
~Worker();
string wno;
virtual std::string getName(){
return name;
}
virtual int getSex(){
return sex;
}
string getWno(){
return wno;
}
};
///////////////////////////////////////////////////////
class InService: public Student, public Worker{
public:
InService(string _name, int _sex, string _sno, string _wno){
Person::name = _name;
Person::sex - _sex;
Worker::wno = _wno;
Student::sno = _sno;
}
};
///////////////////////////////////////////////////////
//main.cpp
#include <iostream>
#include "inservice.h"
using namespace std;
int main() {
string name, sno, wno;
int sex;
cin >> name;
cin >> sex;
cin >> sno;
cin >> wno;
InService is(name, sex, sno, wno);
Person* p = &is;
Student* s = &is;
Worker* w = &is;
cout << p->getName() << endl;
cout << p->getSex() << endl;
cout << s->getName() << endl;
cout << s->getSex() << endl;
cout << s->getSno() << endl;
cout << w->getName() << endl;
cout << w->getSex() << endl;
cout << w->getWno() << endl;
return 0;
}
Suppose my input is:
Jack
1 //1-for male; 0 -for female
12345678 //studentNo
87654321 //workerNo
I expect the output to be:
Jack
1
12345678
Jack
1
87654321
InService(string _name, int _sex, string _sno, string _wno){
Person::name = _name;
Person::sex - _sex;
Worker::wno = _wno;
Student::sno = _sno;
}
There's a typo there, Person::sex - _sex; should be Person::sex = _sex;
Also you can remove name and sex virtual function and have it just a standard function in Person, since it's exactly the same for all classes that derive from it. That will remove the ambiguity of which getName and getSex function that InService class virtual table needs to point to.
I've been working on this assignment for a while. Here's the instructions:
You are to design an abstract class called Employee whose members are
as given below (make them protected):
Data members: char *name, long int ID
Two constructors: A Default constructor // intitialize data memebrs to
the default values and a copy constructor
Methods: setPerson (char *n, long int id) //allows user to set
information for each person A function called Print () // should be a
virtual function, that prints the data attributes of the class. and a
destructor
Also define two classes that derived from class Employee, called
Manager and Secretary. Each class should inherit all members from the
base class and has its own data members and member functions as well.
The Manager should have a data member called degree for his/her
undergraduate degree (e.g. diploma, bachelor, master, doctor), the
Secretary should have her contract (can be a Boolean value 1/0 for
permanent/temporary).
All member functions of derived class should be overrided from their
base class.
Write the following main() to test your classes
int main() {
Employee * p = new Manager(“Bruce Lee”, 0234567, “Dr.”);
P.print();
Secretary p2;
p2.setPerson(“Wilma Jones”, 0341256, “permanent”);
delete p;
p = & p2;
p.Print();
return 0;
}
This is everything I've come up with so far, but I'm pretty sure it's riddled with mistakes and that my arguments and variable types are all off.
#include <iostream>
using namespace std;
class Employee{
protected:
char *name;
long int ID;
public:
Employee();
Employee(Employee&);
void setPerson(char * n, long int eID) {
name = n;
ID = eID; };
virtual void Print(){
cout << "Name: " << name << endl;
cout << "ID: " << ID << endl; };
};
class Manager: public Employee {
protected:
char *degree;
public:
void setPerson(char * n, long int eID, char * d){
name = n;
ID = eID;
degree = d;
};
void Print() {
cout << "Name: " << name << endl;
cout << "ID: " << ID << endl;
cout << "Degree: " << degree << endl;
};
};
class Secretary: public Employee {
protected:
bool contract;
public:
void setPerson(char * n, long int eID, string c){
name = n;
ID = eID;
if (c == "permanent") contract = true;
else contract = false;
};
void Print(){
cout << "Name: " << name << endl;
cout << "ID: " << ID << endl;
cout << "Contract: " << contract << endl;
};
};
int main() {
Employee * P = new Manager("Bruce Lee", 0234567, "Dr.");
P.Print();
Secretary P2;
P2.setPerson("Wilma Jones", 0341256, "permanent");
delete P;
P = & P2;
P.Print();
return 0;
}
I'm getting an error on line 62 (the first line of the main code):
No matching constructor for initialization of Manager
I've tried reading similar questions, but they haven't helped me much. I think the most confusing thing is contract being a bool value and the use of char arguments. Any guidance at all is appreciated.
The error you're getting is pretty straight-forward: you don't have any constructor for Manager (or Employee) that takes a string, integer (?), and string as arguments.
You have declared the constructor employee but not defined it.
Look at the class employee, Under publc you have declared
Employee();
Employee(Employee&);
But you have not defined the function. You need
Employee :: Employee()
{
bla bla bla
}
and another one for the other signature.
I am trying to get this program to start running but currently I just get errors. I am not sure how to get this to work. If I change the class SavingsAccount to public it should be okay, but I am required to keep it as is.
The problem is in the main function.
#include <iostream>
#include <iomanip>
#include <string>
using namespace std;
class SavingsAccount
{
int accountType;
string ownerName;
long ssn;
double accountClosurePenaltyPercent, accountBalance;
void Information();
inline double AccountClosureLoss()
{
return (accountBalance * accountClosurePenaltyPercent);
}
void OutputInformation();
};
void SavingsAccount::Information()
{
cout << "Enter Account Type (1 for Checking or 2 for Savings): ";
cin >> accountType;
cout << "Enter owner name: ";
getline(cin, ownerName);
cout << "Enter the Social Security Number: ";
cin >> ssn;
cout << "Enter the percent penalty for closing account(decimal form): ";
cin >> accountClosurePenaltyPercent;
cout << "Enter the account balance: ";
cin >> accountBalance;
}
void SavingsAccount::OutputInformation()
{
cout << "Account Type: " << endl;
cout << "Name: " << ownerName << endl;
cout << "SSN: " << ssn << endl;
cout << "Account Closure Penaly %: " << accountClosurePenaltyPercent << endl;
cout << "Account Balance: " << accountBalance;
}
int main(void)
{
SavingsAccount.Information();
SavingsAccount.AccountClosureLoss();
SavingsAccount.OutputInformation();
return 0;
}
What I tried so far.
int main(void)
{
SavingsAccount John;
John.Information();
John.AccountClosureLoss();
John.OutputInformation();
return 0;
}
Any suggestions?
Well by default member functions are private, so you can always add them into public as follows:
class SavingsAccount
{
private:
int accountType;
string ownerName;
long ssn;
public:
double accountClosurePenaltyPercent, accountBalance;
void Information();
inline double AccountClosureLoss()
{
return (accountBalance * accountClosurePenaltyPercent);
}
void OutputInformation();
};
You will now be able to call them from the main.
Since you cannot change the SavingsAccount class, and since it prohibits access to it's members (private is the default), you are not supposed to use any menber of that class.
"The problem is in the main function": no, it is in the design of your class. A class with nothing public is not useful.
There is no clean solution to your problem.
A solution on the borderline of changing the class would be in defining an 'interface', and making the (unchanged) class inherit that interface:
class Account {
public:
virtual ~Account(){}
virtual void Information() = 0;
virtual double AccountClosureLoss() = 0;
virtual void OutputInformation() = 0;
};
class SavingsAccout : public Account {
... body remains unchanged
};
The main will use Account iso SavingsAccount:
SavingsAccount savingsAccount;
Account& account = savingsAccount;
// should be accessible via the `Account` interface.
account.AccountClosureLoss();
You're trying to use member attributes inside your methods, yet you're trying to use your methods without an instance. All the member attributes' values are stored inside your instances, so you need an instance first. Add it into your main function:
int main(void)
{
SavingsAccount myAccount;
myAccount.Information();
myAccount.AccountClosureLoss();
myAccount.OutputInformation();
return 0;
}
Also your methods are defined to be private, you should always use public: and private: as following:
class SavingsAccount
{
public:
void Information();
inline double AccountClosureLoss()
{
return (accountBalance * accountClosurePenaltyPercent);
}
void OutputInformation();
private:
int accountType;
string ownerName;
long ssn;
double accountClosurePenaltyPercent;
double accountBalance;
};
You can't use methods without an instance. Even if you could (static maybe?) you can't use any member attributes inside them, so it'd be useless to include it into the class.
You must declare an instance of the SavingsAccount class first. For example:
int main()
{
SavingsAccount account;
account.Information();
...
return 0;
}
Additionally, yes, the methods of the class that you want to call must be public.