可以运营商<<在派生类中调用另一个运算符<<在c ++的基类中?

时间:2013-10-31 15:32:22

标签: c++ operator-overloading operator-keyword derived-class

在我的代码中,Manager源自Employee,并且每个人都有operator<<覆盖。

class Employee{
protected:
    int salary;
    int rank;
public:
    int getSalary()const{return salary;}
    int getRank()const{return rank;}
    Employee(int s, int r):salary(s), rank(r){};
};
ostream& operator<< (ostream& out, Employee& e){
    out << "Salary: " << e.getSalary() << " Rank: " << e.getRank() << endl;
    return out;
}

class Manager: public Employee{
public:
    Manager(int s, int r): Employee(s, r){};
};
ostream& operator<< (ostream& out, Manager& m){   
    out << "Manager: ";
    cout << (Employee)m << endl;  //can not compile, how to call function of Employee?
    return out;
}

我希望cout << (Employee)m << endl;会致电ostream& operator<< (ostream& out, Employee& e),但失败了。

6 个答案:

答案 0 :(得分:7)

转换为引用而不是副本:

cout << (Employee&)m << endl;  //can not compile, how to call function of Employee?

另请注意,ostream运算符绝不是该类的成员(似乎您对问题的标题感到困惑)。

答案 1 :(得分:4)

执行此操作的常用方法是在基类中具有(可能privateprotected)虚拟print(或任何其他合适的名称)函数,派生类可以覆盖

您只提供通用operator<<以获取对基类的引用,并在其中调用print。如果需要,覆盖print函数可以调用基数print

答案 2 :(得分:3)

cout << (Employee)m << endl;更改为cout << (Employee&)m << endl;

错误消息的解释如下:

当你尝试施放(Employee)m时,你正在创建一个临时的。 operator<<重载需要引用。你不能参考临时的。

因为你真的只是希望它打印自己的数据(不是自己的副本),所以你将你所引用的引用转换为你需要的类型的引用(它是基类)。

正如jrok在answer中指出的那样,你也可以通过提供一个打印数据的虚函数来实现这一目标。这将是一种更简单的方法,因为它不需要为每个派生类重载operator<<

答案 3 :(得分:1)

你的超载:

ostream& operator<< (ostream& out, Employee& e)

仅适用于对Employee个对象的引用,因此它不适用于非引用值(如转换的结果)。

通常,原型将是:

ostream& operator<< (ostream& out, const Employee& e)

还可以确保打印员工不会改变它。如果你改变它,事情应该工作得很好。 (ostream& 必须是引用,而不是const引用,因为ostream会被打印操作变异。)

答案 4 :(得分:0)

有两个问题合并使你的编译失败。

(1)本声明和定义:

    ostream& operator<< (ostream& out, Employee& e){
        out << "Salary: " << e.getSalary() << " Rank: " << e.getRank() << endl;
        return out;
    }

尽管您没有更改e,但您可以参考非const。这禁止您在右值上调用此运算符。

(2)这一行

cout << (Employee)m << endl;

正如其他人所说,你正在切割m。此外,广告(Employee) m会返回一个临时Employee,这是一个右值。

总之,强制转换(Employee)m会产生一个无法绑定到e的右值。

您可以修复其中一个以构建代码编译器,但最好修复这两个问题以使代码更加健壮:

// ...
ostream& operator<< (ostream& out, const Employee& e) {
// ...

// ...
cout << static_cast<Employee&>(m) << endl;
// ...

答案 5 :(得分:0)

首先,重载全局函数。这是另一个概念,而不是重写。见Override and overload in C++

接下来,你的演员是错的。这应该做:

ostream& operator<< (ostream& out, Manager& m){   
    out << "Manager: ";
    cout << static_cast<Employee&>(m) << endl;  //can not compile, [...]?
   return out;
}

...如果您真的想要重载全局<<运算符。

相关问题