在我的代码中,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)
,但失败了。
答案 0 :(得分:7)
转换为引用而不是副本:
cout << (Employee&)m << endl; //can not compile, how to call function of Employee?
另请注意,ostream运算符绝不是该类的成员(似乎您对问题的标题感到困惑)。
答案 1 :(得分:4)
执行此操作的常用方法是在基类中具有(可能private
或protected
)虚拟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;
}
...如果您真的想要重载全局<<
运算符。