C++ Can操作员<&书信电报;在派生类中调用另一个运算符<&书信电报;在c+中的基类中+;?
在我的代码中,C++ Can操作员<&书信电报;在派生类中调用另一个运算符<&书信电报;在c+中的基类中+;?,c++,operator-overloading,operator-keyword,derived-class,C++,Operator Overloading,Operator Keyword,Derived Class,在我的代码中,Manager是从Employee派生而来的,每个人都有一个操作符转换为引用,而不是副本: cout << (Employee&)m << endl; //can not compile, how to call function of Employee? cout转换为引用而不是副本: cout << (Employee&)m << endl; //can not compile, how to call fu
Manager
是从Employee
派生而来的,每个人都有一个操作符转换为引用,而不是副本:
cout << (Employee&)m << endl; //can not compile, how to call function of Employee?
cout转换为引用而不是副本:
cout << (Employee&)m << endl; //can not compile, how to call function of Employee?
cout通常的方法是在派生类可以覆盖的基类中有一个(可能是private
或protected
)虚拟print
(或任何其他合适的名称)函数
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;
}
您只提供常规操作符通常的方法是在派生类可以覆盖的基类中具有(可能是私有的
或受保护的
)虚拟的打印
(或任何其他合适的名称)函数
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;
}
您只提供常规运算符您的重载:
ostream& operator<< (ostream& out, Employee& e)
这也保证了打印员工不会使其发生变异。如果你改变这一点,事情应该会很顺利。(ostream&
必须是引用,而不是常量引用,因为打印操作会使ostream
发生变异。)您的重载:
ostream& operator<< (ostream& out, Employee& e)
这也保证了打印员工不会使其发生变异。如果你改变这一点,事情应该会很顺利。(ostream&
必须是一个引用,而不是常量引用,因为打印操作会使ostream
发生变异。)ChangecoutChangecout有两个问题组合在一起会导致编译失败
(1) 本声明和定义:
ostream& operator<< (ostream& out, Employee& e){
out << "Salary: " << e.getSalary() << " Rank: " << e.getRank() << endl;
return out;
}
正如其他人所说,您正在切片m
。此外,cast(Employee)m
返回一个临时Employee
,它是一个右值
总之,cast(Employee)m
生成一个不能绑定到e
的右值
您可以修复其中一个以使代码编译器更健壮,但最好同时修复这两个问题以使代码更健壮:
// ...
ostream& operator<< (ostream& out, const Employee& e) {
// ...
// ...
cout << static_cast<Employee&>(m) << endl;
// ...
/。。。
ostream&operator有两个问题共同导致编译失败
(1) 本声明和定义:
ostream& operator<< (ostream& out, Employee& e){
out << "Salary: " << e.getSalary() << " Rank: " << e.getRank() << endl;
return out;
}
正如其他人所说,您正在切片m
。此外,cast(Employee)m
返回一个临时Employee
,它是一个右值
总之,cast(Employee)m
生成一个不能绑定到e
的右值
您可以修复其中一个以使代码编译器更健壮,但最好同时修复这两个问题以使代码更健壮:
// ...
ostream& operator<< (ostream& out, const Employee& e) {
// ...
// ...
cout << static_cast<Employee&>(m) << endl;
// ...
/。。。
ostream&operator首先,重载一个全局函数。这是超越之外的另一个概念。看
其次,你的演员阵容是错误的。这应该做到:
ostream& operator<< (ostream& out, Manager& m){
out << "Manager: ";
cout << static_cast<Employee&>(m) << endl; //can not compile, [...]?
return out;
}
ostream&operator首先,重载一个全局函数。这是超越之外的另一个概念。看
其次,你的演员阵容是错误的。这应该做到:
ostream& operator<< (ostream& out, Manager& m){
out << "Manager: ";
cout << static_cast<Employee&>(m) << endl; //can not compile, [...]?
return out;
}
ostream&operator编译错误是什么?您正在切片(至少代码正在尝试查找)。您需要编写static\u cast(m)
而不是(Employee)m
@ScarletAmaranth它应该无法编译,因为临时员工
无法绑定到员工&
。如果您使用的是MSVC,那么它有一个非常愚蠢的扩展,允许这种危险的行为。(Employee)m
将生成m的Employee部分的副本,该副本是临时的。我认为它不能匹配您过载的Employee&e
参数。@Simple:幸运的是,g++会因此而严厉惩罚您。:)编译错误是什么?您正在切片(至少代码正在尝试查找它)。您需要编写static\u cast(m)
而不是(Employee)m
@ScarletAmaranth它应该无法编译,因为临时员工
无法绑定到员工&
。如果您使用的是MSVC,那么它有一个非常愚蠢的扩展,允许这种危险的行为。(Employee)m
将生成m的Employee部分的副本,该副本是临时的。我认为它不能匹配您过载的Employee&e
参数。@Simple:幸运的是,g++会因此而严厉惩罚您。:)他的operator@ZacHowland我看这没什么问题。您可以像流运算符一样将它们声明为朋友。@jrok。很抱歉我只是不认为这是一个真正的OP问题的答案。尽管你所说的是正确的。我没有投反对票,但当这个问题可以用静态类型解决时,引入多态性似乎是一种耻辱。@jrok我并不是把它说成一个问题,只是作为一个注释(你第二段的第一句暗示它是一个类成员——它可以,但不是在这个特殊情况下).他的operator@ZacHowland我看这没什么问题。您可以像流运算符一样将它们声明为朋友。@jrok。很抱歉我只是不认为这是一个真正的OP问题的答案。尽管你所说的是正确的。我没有投反对票,但当这个问题可以用静态类型解决时,引入多态性似乎是一种耻辱。@jrok我并不是把它说成一个问题,只是作为一个注释(你第二段的第一句暗示它是一个类成员——它可以,但不是在这个特殊情况下)DavidRodríguez dribeas我就是这么说的。我错过什么了吗?对不起。。。我错过了something@DavidRodr我就是这么说的。我错过什么了吗?对不起。。。我错过了一些东西