2015-02-11 4 views
2

Я работаю над проектом для своей школы на C++Переопределение оператора << в C++

У меня 2 класса: работник и учитель. Учитель, полученный от Employe, и имеет переопределения его функций.

Мы переопределяем оператора <<, чтобы напечатать некоторую информацию о Работниках или Учителях. Каждый класс имеет const int attribute LevelAcces_. Для служащий, это и Учитель это .

Когда я создаю Учителя в моем main.cpp, я вызываю переопределение оператора < < Учителя, чтобы распечатать его информацию. Так эта функция называется:

ostream& operator<<(ostream& os, const Teacher& pTeacher){ 
    os << (pTeacher); 
    return os; 
} 

Но функция называет себя с линией "os << (pTeacher);" и делает петлю, которая вызывает переполнение стека.

Я хочу, что линия "os << (pTeacher)" называет оператора < < моего класса, а не служащий моего класса Учителя.

Переопределение оператора < < в служащем:

ostream& operator<<(ostream& os, const Employe& pEmploye){ 
    os << "Name: " << pEmploye.name_ << endl; 
    os << "Class: " << pEmploye.getClass() << endl; 
    os << "LevelAcces: " << pEmploye.getLevelAccess() << endl; 
    return os; 
} 

Я пытался бросить свой Учитель в служащий, но когда он печатает сообщение, LevelAcces 5 (и я хочу 20, потому что мой служащий является учителем).

Я также пытался использовать оператор :: служащий < < но оператор < < не является членом так что служащий не работает ...

Итак, вот мой вопрос:

Как я могу использовать мой оператор < < сотрудника в моем кабинете < < преподавателя и печатать правильную информацию (LevelAccess = 20, а не 5)?

Я также думал о «виртуальном», но наш профессор говорит нам, что не нужно использовать это слово.

Заранее спасибо :)

Вот более полный код:

main.cpp:

Teacher Garry("Garry"); 
cout << Garry << endl; 

Employe.cpp:

#include "Employe.h" 

using namespace std; 

Employe::Employe(){ 
    name_ = ""; 
} 

Employe::Employe(string pName){ 
    name_ = pName; 
} 

string Employe::getName() const{ 
    return name_; 
} 

unsigned int Employe::getLevelAccess() const{ 
    return levelAccess_; 
} 

string Employe::getClass() const{ 
    return typeid(*this).name(); 
} 

ostream& operator<<(ostream& os, const Employe& pEmploye){ 
    os << "Name: " << pEmploye.name_ << endl; 
    os << "Class: " << pEmploye.getClass() << endl; 
    os << "LevelAcces: " << pEmploye.getLevelAccess() << endl; 
    return os; 
} 

С этой служащий.ч:

private: 
    static const unsigned int LevelAccess_ = 5; 

Teacher.cpp:

#include "teacher.h" 
using namespace std; 

Teacher::Teacher(string pName){ 
    nom_ = pName; 
} 

unsigned int Teacher::getLevelAccess() const{ 
    return(Employe::getLevelAccess() + accessTeacher_); 
} 
string Teacher::getClass() const{ 
    return typeid(*this).name(); 
} 

ostream& operator<<(ostream& os, const Teacher& pTeacher){ 
     os << (pTeacher); 
     return os; 
} 

С этого Teacher.h:

static const unsigned int accesTeacher_ = 15; 
+1

Пожалуйста, укажите в своем вопросе определения Учителя и Работника. –

+0

Любой подходящий код для этого, который вы могли бы публиковать? Пример COMPLETE был бы ДЕЙСТВИТЕЛЬНО хорош, но по крайней мере код, который устанавливает 'accessEmploye_' в разные значения, будет началом ... –

ответ

1

Вы можете использовать бросок:

os << static_cast<const Employe &>(pTeacher); 

& является важный.

Чтобы сделать вызов функции функции-члена Teacher::getLevelAccess() с помощью ссылки Employe, вы должны сделать эту функцию виртуальной. (Сделайте это в teacher.h). getClass() также должен быть virtual.


NB. Вы продолжаете говорить такие вещи, как «Переопределение operator<< в Employe:», однако вы не перегрузили operator<< в Employe. У вас есть свободная функция, которая принимает Employe как аргумент.

+0

@WhozCraig обновлен –

+0

... и код полностью изменен сейчас –

+0

Ненависть, когда это произойдет = ( – WhozCraig

2

Что я хотел бы сделать это следующим образом: определить только один

ostream& operator<<(ostream& os, const Employe& pEmploye) 
{ 
    return pEmploye.display(os); 
} 

для основания иерархии, в которых вы называете защищенную функцию virtual display() члена, который преодолено каждым производным классом и который дисплей делегируется. Это когда-то вызывает идиому NVI (не виртуального интерфейса). Он работает следующим образом:

class Employee 
{ 
    // ... 
    friend ostream& operator<<(ostream& os, const Employee& pEmployee) 
    { 
     return pEmployee.display(os); 
    } 
protected: 
    virtual ostream& display(ostream& os) const 
    { 
     // implement it here 
     return os; 
    } 
}; 

class Teacher: public Employee 
{ 
    // .... 
protected: 
    ostream& display(ostream& os) const override 
    { 
     // implement it here 
     return os; 
    } 
}; 
+0

Это хорошая идея, но мой учитель говорит: «В Учителе используйте оператор функции друга <<, чтобы напечатать все атрибуты Учителя (подумайте, чтобы использовать оператор << of Employe)». И я не могу создайте другую функцию (у меня есть бумага, в которой написана вся функция, которую я должен создать). – Aymeric

+0

@ Эймер, хорошо, затем используйте предложение Мэтта с кастингом. – vsoftco

Смежные вопросы