2015-12-08 3 views
2

У меня есть родительский класс: сотрудник с двумя унаследованными классами: Hourly and Salary В родительском классе я перегрузил < <, поэтому он выведет все значения переменных из сотрудника. Мне нужно создать 3 новых сотрудников: 2 Hourly и 1 Salary, но мои конструкторы, похоже, работают некорректно. Программа будет компилироваться, но когда я вызываю конструктор Hourly, программа перестает работать (переполнение стека?). Вот код:Конструкторы в унаследованных классах C++

class employee 
{ 
    friend ostream& operator<<(ostream& out, const employee& emp); 

    public: 

    employee(); 
    employee(string id, string fname, string lname, string bDate, string hDate, double pay); 
    ~employee(); 
    void setEmpId(string id); 
    string getEmpID(); 
    void setFirstName(string name); 
    string getFirstName(); 
    void setLastName(string name); 
    string getLastName(); 
    void setBirthDate(string birthDate); 
    string getBirthDate(); 
    void setHireDate(string hireDate); 
    string getHireDate(); 
    void setPayRate(double rate); 
    double getPayRate(); 

    protected: 

    string employee_id; 
    string first_name; 
    string last_name; 
    string birth_date; 
    string hire_date; 
    double pay_rate; 
}; 

Это мой родительский класс и вот мои два наследуемые классы:

class Hourly : public employee 
{ 
    public: 

    Hourly(string fname, string lname, string bdate, string hdate, double rate, string id) 
    { 
     int random = rand() % 1000; 
     this->employee_id=id; 
     this->first_name=fname; 
     this->last_name=lname; 
     this->birth_date=bdate; 
     this->hire_date=hdate; 
     this->pay_rate=rate; 
    } 
}; 

Зарплата класс, по существу, то же самое, как прямо сейчас. Вот где я пытаюсь создать свой почасовой работник:

employee empOne = Hourly("Brian", "Finn", "1/12/1995", "1/12/2015", 7.25, "1215"); 
cout << empOne; 

Я знаю, что он никогда не получает мимо конструктора, потому что я пытался CO тесты и программа никогда не делает это так далеко.

+0

Это на самом деле не свойственно принимать плагиатом ответ. – g24l

ответ

1

Полиморфизм полиморфизма не существует с семантикой значений. Он должен быть ссылкой или указателем, поэтому объект нарезается в своем назначении объекту employee, и вы получите employee, а не Hourly. Вы можете остановить это, создав объект в куче. Также вы должны определять деструктор базовых классов как виртуальный, иначе неправильный деструктор будет вызываться при удалении с помощью указателя базового класса.

Наконец, вы должны вызвать конструктор базовых классов в конструкторе производных классов.

Со всеми этими изменениями он отлично подходит для меня.

#include <iostream> 
#include <string> 
#include <cstdlib> 

using std::cout; 
using std::string; 
using std::ostream; 

class employee 
{ 
    friend ostream& operator<<(ostream& out, const employee& emp); 

    public: 
    employee(); 
    employee(string const& id, string const& fname, string const& lname, string const& bDate, string const& hDate, double pay) 
     : employee_id(id), first_name(fname), last_name(lname), birth_date(bDate), hire_date(hDate), pay_rate(pay) 
    {} 
    virtual ~employee(){};  

    protected: 
    string employee_id; 
    string first_name; 
    string last_name; 
    string birth_date; 
    string hire_date; 
    double pay_rate; 
}; 

ostream& operator<<(ostream& out, const employee& emp) 
{ 
    out << emp.employee_id; 
    return out; 
} 

class Hourly : public employee 
{ 

public: 
Hourly(string const& fname, string const& lname, string const& bdate, string const& hdate, double rate, string const& id) 
    : employee(id, fname, lname, bdate, hdate, rate) 
{ 
    int random = rand() % 1000; 
} 
}; 

void printEmployee(employee& e) 
{ 
    cout << e << '\n'; 
} 

int main() 
{ 
    // using reference semantics 
    Hourly empOne = Hourly("Brian", "Finn", "1/12/1995", "1/12/2015", 7.25, "1215"); 
    printEmployee(empOne); 

    // using pointer semantics 
    employee* empTwo = new Hourly("Dave", "Smith", "1/12/1995", "1/12/2015", 7.25, "1216"); 
    cout << *empTwo << '\n'; 
    delete empTwo; // would be better to use a `unique_ptr` and you wont need a delete. 
} 
1

Вы проблема заключается в том, что вы назначаете объект на объект базового класса, а затем вы slice его.

employee empOne = Hourly("Brian", "Finn", "1/12/1995", "1/12/2015", 
7.25, "1215"); 

Ваш конструктор пытается уступке с wrong aliasing и приводит к аварии (обратите внимание на использование указателя этого в конструкторе). Вы можете преодолеть первую часть, выполнив инициализацию в списке инициализаторов вашего конструктора. Однако нарезка все еще происходит.

Вы должны либо присвоить его объявленному классу, либо удержать его указателем базового класса.

например. 1

Hourly empOne = Hourly("Brian", "Finn", "1/12/1995", "1/12/2015", 7.25, "1215"); 

e.g. 2

employee * empOne = new Hourly("Brian", "Finn", "1/12/1995", "1/12/2015", 7.25, "1215"); 

Для последней работы вам необходимо определить деструктор виртуального базового класса.

virtual ~employee() = default; 
0

В операторе присваивания ниже почасовой типа sliced.

employee empOne = Hourly("Brian", "Finn", "1/12/1995", "1/12/2015", 7.25, "1215"); 

Я подозреваю, что следующий будет работать

Hourly hourlyEmp("Brian", "Finn", "1/12/1995", "1/12/2015", 7.25, "1215"); 
cout << hourlyEmp; 
Смежные вопросы