2015-02-11 116 views
2

我正在为我的学校在C++中的项目工作覆盖的运算符<< in C++

我有2个班级:雇主和老师。 老师派生自Employe并且覆盖了他的职能。

我们重写运营商<<以打印雇主或教师的一些信息。 每个班级都有一个const int attribute LevelAcces_。 对于雇工,这是和教师它。

当我在main.cpp中创建一个教师时,我打电话给老师的操作员< <的覆盖来打印他的信息。 所以这个函数被调用:

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

但是,在函数调用自身与线"os << (pTeacher);"做一个循环,导致堆栈溢出

我希望行"os << (pTeacher)"调用我的班级Employe的运营商< <而不是我的班级老师。在雇工经营者< <的

覆盖:

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,因为我的雇工是老师)。

我还试图用雇工::操作< <但运营商< <不是雇工所以它不工作的一员......

所以,这里是我的问题:

我该如何使用我的Operator的运营商< <在我的老师< < <中打印正确的信息(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; 
} 

有了这个雇员。H:

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

请在您的问题中显示教师和员工的定义。 – 2015-02-11 23:30:25

+0

任何相关的代码,你可以发布?一个完整的例子将是非常好的,但至少将'accessEmploye_'设置为不同值的代码将是一个开始... – 2015-02-11 23:30:45

回答

1

您可以使用强制:

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

&是重要。

要从Employe引用中调用成员函数调用Teacher::getLevelAccess(),必须使该函数为虚拟。 (在teacher.h中执行此操作)。 getClass()也应该是virtual


NB。你继续说“在雇主中覆盖operator<<”,但是你没有在雇主中重载operator<<。你有一个免费的功能,它需要Employe作为参数。

+0

@WhozCraig更新 – 2015-02-11 23:46:58

+0

... aand代码现在完全改变 – 2015-02-11 23:48:13

+0

当这种情况发生= =( – WhozCraig 2015-02-12 05:24:29

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 2015-02-12 00:05:24

+0

@America,好吧,然后使用马特的建议与铸造。 – vsoftco 2015-02-12 00:06:12