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.
Related
We're learning about constructors in class and I was trying to experiment with an overloaded constructor. When I run my program I keep getting an error written in the color red that says...
~
The ampersand (&) character is not allowed. The & operator is reserved for future use; wrap an ampersand in double quotation marks ("&") to pass it as part of a string.
^This only happens when I try to use private variables, when everything is public nothing goes wrong.
///Here's my code
#include <iostream>
using namespace std;
class JCole {
private:
string song;
string album;
int albumNum;
JCole::JCole(string _song, string _album, int _Num) {
song = _song;
album = _album;
albumNum = _Num;
}
};
int main() {
JCole album1("Punchin the clock", "The Off-Season", 6);
JCole album2("ATM","KOD",5);
cout << album1.song << " " << album1.album << " " << album1.albumNum << endl;
cout << album2.song << " " << album2.album << " " << album2.albumNum << endl;
return 0;
}
Your constructor is declared as private because you haven't changed the access setting.
Try this:
class JCole {
private:
string song;
string album;
int albumNum;
// Insert:
public:
JCole::JCole(string _song, string _album, int _Num) {
song = _song;
album = _album;
albumNum = _Num;
}
};
A private constructor is a nasty thing; only members of the class can call it. Thus wreaking havoc with external code that wants to instantiate this class.
Also, you can use many public:, private:, protected: within your class and in any order.
My task was to create an object in class, initialize it and output(using pointer to class). This code compiles perfectly, but the output doesn't appear. I would really appreciate any help, thank you in advance!
#include <iostream>
#include <string>
using namespace std;
class family
{
public:
void setWife(string w)
{w = wife;};
string getWife()
{return wife;};
void setHusband(string h)
{husband = h;};
string getHusband()
{return husband;};
void setSon(string s)
{s = son;};
string getSon()
{return son;};
void setDaughter1(string d1)
{d1 = daughter1;};
string getDaughter1()
{return daughter1;};
void setDaughter2(string d2)
{daughter2 = d2;};
string getDaughter2()
{return daughter2;};
double* getPointer()
{return &pointer;};
void initialize()
{
setWife("Shirley Collin");
setHusband("Donald Collin");
setSon("Collin Collin");
setDaughter1("Harriet Collin");
setDaughter2("Hillary Collin");
}
friend void output(family* Collin);
private:
string wife;
string husband;
string son;
string daughter1;
string daughter2;
double pointer;
};
void output(family* Collin)
{cout << "Husband is " <<Collin->getHusband()<< endl;
cout << "wife is " << Collin ->getWife() << endl;
cout << "son is " << Collin->getSon() << endl;
cout << "daughter1 is " << Collin->getDaughter1() << endl;
cout << "daughter2 is " << Collin->getDaughter2()<< endl;
};
int main()
{family Collin;
Collin.initialize();
family *pointer = new family;
output (pointer);
cin.ignore();
}
family Collin;
Collin.initialize();
This constructs an instance of the family class, and initializes it with the values defined in the initialize() method.
family *pointer = new family;
output (pointer);
This constructs a second instance of the family class, does not initialize it in any way, and calls the output() method, to display the contents of the completely uninitialized second instance of this family class.
This is why this program produces no useful output.
You probably want to replace these four lines with:
family *pointer=new family;
pointer->initialize();
output(pointer);
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;}
};
I have Base and Derived class
Base :
class Person{
public:
Person(string name , int age ){
this -> name = name;
this -> age = age;
}
virtual void getInfo(){
cout << "Person " << name << " " << age;
}
protected:
string name;
int age;
};
Derived:
class Kid : public Person{
public:
Kid(string name, int age):Person(name,age){};
virtual void getInfo( ){
cout << "Kid " << name << " " << age;
}
};
class Adult : public Person{
public:
Adult(string name, int age):Person(name,age){};
virtual void getInfo( ){
cout << "Adult " << name << " " << age;
}
};
When i do something like
map<string ,Person*> m;
Person *one;
Person *three;
Kid two("Mathew",15);
Adult four("JOhn",55);
three = &four;
one = &two;
m["first"] = one;
m["second"] = three;
for( auto &x : m )
x.second-> getInfo();
return 0;
It nicely prints info as it should // "Adult" for adult class and "Kid" for kid class
however when i edit the class and move the map into base class. e.g and create Add method.
class Person{
public:
Person(string name , int age ){
this -> name = name;
this -> age = age;
}
virtual void getInfo(){
cout << "Person " << name << " " << age;
}
void add( string name , Person a){
Person *one = &a;
m[ name ] = one;
}
void print(){
for( auto &x: m )
x.second -> getInfo()
}
protected:
string name;
int age;
map< string , Person*> m;
};
Person one("John", 25);
one.add("first",Kid("Mathew",15));
one.add("second",Adult("Leo",55));
one.print();
It throws seg fault , why is this happening? Its basicly the same implementation with using of method. What causes the seg fault? Is there a way how to fix it?
// EDIT
I tried using unique_ptr redecaring map as
map< string , unique_ptr<Person>> m;
AddField (string name , Person a ){
m[name] = ( unique_ptr<Person> (a));
return *this;
}
or
properties[name] = unique_ptr<Person> ( new Person( a ));
or
AddField (string name , Person a ){
CData *one = unique_ptr<Person>(new Person(a));
m[name] = one ;
return *this;
}
I am not experienced with unique/share ptr.
This threw
‘std::unique_ptr’ to ‘Person*’
Firstly, let's understand what the map is actually storing:
map< string , Person*> m;
This map binds a string to a Person*, which is a memory address pointing to a person. The map does not actually store the person instance, only its memory address.
Now let's analyze your two situations.
map<string ,Person*> m;
// Allocating space for two memory addresses on the stack:
Person *one;
Person *three;
// Creating two instances on the stack:
Kid two("Mathew",15);
Adult four("JOhn",55);
// Setting the pointers to the memory addresses of the instances on the stack:
three = &four;
one = &two;
m["first"] = one;
m["second"] = three;
for( auto &x : m )
x.second-> getInfo();
return 0;
// End of the function: now all objects are destroyed in reverse order.
The instances two and four live on the stack and are destroyed at the end of the scope (after return 0;). Taking their memory addresses and storing them into one and three is fine, as the pointers will outlive two and four.
Person one("John", 25);
// Creating a Kid instance without a name (temporary).
// The Kid instance goes out of scope immediately and is destroyed:
one.add("first",Kid("Mathew",15));
// Creating an Adult instance without a name (temporary).
// The Adult instance goes out of scope immediately and is destroyed:
one.add("second",Adult("Leo",55));
one.print();
The issue here is that the instances you are creating are destroyed too soon. You need to manage their lifetime properly to ensure that the memory address you're inserting into the map does not outlive the data in the pointed memory location.
Another major issue is that you're accepting add's Person a parameter by value. This will create a copy of the passed instance.
// Copy the passed instance:
void add( string name , Person a){
// Take memory address of the copied instance:
Person *one = &a;
m[ name ] = one;
// The copied instance is destroyed here!
}
You should take a as a reference, in order to avoid copies and object slicing:
void add( string name , Person& a){
m[ name ] = &a;
}
Here's a working example, after correcting a's signature:
Kid k("Mathew",15);
Adult a("Leo",55);
// k and a will outlive one.
Person one("John", 25);
one.add("first", k);
one.add("second", a);
one.print();
// one gets destroyed.
// a gets destroyed.
// k gets destroyed.
I had a go at trying to solve your issue and I came up an initial version of this. Which I'm not really happy with.
#include<iostream>
#include<map>
#include<memory>
#include<string>
/* used to simplify example code (not a good
idea in production code especially header files)
*/
using namespace std;
class Person
{
public:
virtual void getInfo() const = 0;
virtual ~Person()
{};
void add(std::shared_ptr<Person> a)
{
m_[a->name_] = a;
}
void print() const
{
getInfo();
for( auto &x: m_ )
x.second->getInfo();
}
protected:
Person(const string& name, int age)
: name_(name), age_(age)
{}
string name_;
int age_;
map<string , std::shared_ptr<Person>> m_;
};
class Kid : public Person
{
public:
Kid(const string& name, int age)
: Person(name, age)
{};
virtual void getInfo() const override
{
cout << "Kid " << name_ << " " << age_ << '\n';
}
};
class Adult : public Person
{
public:
Adult(const string& name, int age)
: Person(name, age)
{};
virtual void getInfo() const override
{
cout << "Adult " << name_ << " " << age_ << '\n';
}
};
int main()
{
auto a = Adult("steve", 35);
auto k1 = make_shared<Kid>("ben", 7);
auto k2 = make_shared<Kid>("emily", 12);
a.add(k1);
a.add(k2);
a.print();
}
I used shared_ptr as I'm guessing later you might want to retrieve those Persons from the map and return them from a getter call. So in that case unique_ptr makes no sense.
I think this version puts too much burden on the caller to create the shared_ptrs. Without knowing exactly what you plan to do though its difficult to suggest an alternative.
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.