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
发生变异。)

Change
coutChange
cout有两个问题组合在一起会导致编译失败

(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我就是这么说的。我错过什么了吗?对不起。。。我错过了一些东西