1

私のコードで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)たのですが、失敗しました。

4

6 に答える 6

8

コピーではなく参照にキャストします。

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

また、ostream オペレーターは決してクラスのメンバーではないことに注意してください (質問のタイトルから混乱しているようです)。

于 2013-10-31T15:35:55.717 に答える
4

に変更cout << (Employee)m << endl;cout << (Employee&)m << endl;ます。

エラーメッセージの説明は次のとおりです。

キャストを試みると(Employee)m、一時的なものを作成しています。オーバーロードは参照operator<<を取ります。一時的なものへの参照はできません。

本当にそれ自体のデータを印刷したいだけなので(それ自体のコピーを作成するのではなく)、必要なタイプの参照に参照をキャストします(基本クラスです)。

jrok が彼の回答で指摘したように、データを印刷する仮想関数を提供することでこれを達成することもできます。operator<<すべての派生クラスをオーバーロードする必要がないため、これはより単純なアプローチになります。

于 2013-10-31T15:40:26.250 に答える
4

これを行う通常の方法は、派生クラスがオーバーライドできる基本クラスに仮想(privateまたはその他の適切な名前) 関数を含めることです。protectedprint

基本クラスへの参照に一般的なものを提供し、その内部でoperator<<呼び出すだけです。printオーバーライドprint関数はprint、必要に応じてベースの を呼び出すことができます。

于 2013-10-31T15:36:14.577 に答える
1

あなたの過負荷:

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

オブジェクトへの参照に対してのみ機能するためEmployee、非参照値 (キャストの結果など) では機能しません。

通常、プロトタイプは次のようになります。

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

これにより、従業員を印刷しても変更されないという安心感も得られます。それを変更すると、問題なく動作するはずです。(ostream& ostream印刷操作によって変更されるため、 const 参照ではなく、参照である必要があります。)

于 2013-10-31T15:39:22.950 に答える
0

まず、グローバル関数をオーバーロードします。これはオーバーライドとは別の概念です。C++ でのオーバーライドとオーバーロードを参照してください

次に、キャストが間違っています。これは次のことを行う必要があります。

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

<<...本当にグローバル演算子をオーバーロードしたい場合。

于 2013-10-31T16:00:23.040 に答える
0

コンパイルが失敗する原因となる 2 つの問題があります。

(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;
// ...
于 2013-10-31T15:52:01.187 に答える