0

オーバーロードを練習するためにこの簡単なプログラムを書きました。

これは私のコードです:

#include <iostream>
#include <string>
using namespace std;

class sex_t
{
    private:
        char __sex__;

    public:
        sex_t(char sex_v = 'M'):__sex__(sex_v)
        {
            if (sex_v != 'M' && sex_v != 'F')
            {
                cerr << "Sex type error!" << sex_v << endl;
                __sex__ = 'M';
            }
        }

        const ostream& operator << (const ostream& stream)
        {
            if (__sex__ == 'M')
                cout << "Male";
            else
                cout << "Female";
            return stream;
        }
};

int main(int argc, char *argv[])
{
    sex_t me('M');
    cout << me << endl;
    return 0;
}

私がそれをコンパイルすると、それはたくさんのエラーメッセージを出力します:

エラーメッセージはめちゃくちゃでした。

役に立つメッセージを見つけるのは難しすぎます。

sex.cpp: 在函数‘int main(int, char**)’中:
sex.cpp:32:10: 错误: ‘operator<<’在‘std::cout << me’中没有匹配
sex.cpp:32:10: 附注: 备选是:
/usr/include/c++/4.6/ostream:110:7: 附注: std::basic_ostream<_CharT, _Traits>::__ostream_type& std::basic_ostream<_CharT, _Traits>::operator<<(std::basic_ostre
4

3 に答える 3

4

引数とoperator<<returnfromは非定数です。また、非メンバーである必要があります-me << coutではなく、のオーバーロードを記述しましたcout << me。また、2つのアンダースコアで始まる識別子は実装用に予約されており、それらを使用することは未定義動作です。

于 2012-06-27T03:02:55.427 に答える
3

「C++ Primer 4th Edition」第 14 章セクション 14.2 入力および出力演算子:

IO 演算子は非メンバー関数である必要があります。演算子を独自のクラスのメンバーにすることはできません。もしそうなら、左側のオペランドは私たちのクラス型のオブジェクトでなければなりません:

// if operator<< is a member of Sales_item
     Sales_item item;
     item << cout;

オーバーロードされた出力演算子の一般的なスケルトンは次のとおりです。

   // general skeleton of the overloaded output operator
     ostream&
     operator <<(ostream& os, const ClassType &object)
     {
         // any special logic to prepare object

         // actual output of members
         os << // ...

         // return ostream object
         return os;
     }

最初のパラメーターは、出力が生成される ostream オブジェクトへの参照です。ストリームへの書き込みによって状態が変化するため、ostream は非定数です。ostream オブジェクトをコピーできないため、パラメーターは参照です。

2 番目のパラメーターは通常、出力するクラス型への const 参照にする必要があります。パラメータは、引数のコピーを避けるための参照です。(通常) オブジェクトを印刷してもオブジェクトは変更されないため、const にすることができます。パラメータを const 参照にすることで、単一の定義を使用して const オブジェクトと非 const オブジェクトを出力できます。

戻り型は ostream 参照です。その値は通常、出力演算子が適用される ostream オブジェクトです。

編集

コードを変更しようとしましたが、__sex__assex_tのプライベート メンバーを使用する場合get functionは、'M' または 'F' を取得するために別のメンバーを作成する必要があります。operator<<関数内でそれを呼び出すと、おそらくエラーが発生します。 const 参照は const 関数しか呼び出すことができないためget function、念のために const 関数を作成する必要があります:)

于 2012-06-27T03:11:48.267 に答える
1

ストリームをオーバーロードするときは、<< 演算子をグローバルに、および/またはfriendクラスに対して (利点のある) として宣言して、その「プライベート メンバー」にアクセスできるようにします (ああ...)。クラス内でafriendを宣言して、グローバルに宣言できます。constストリームでは使用しないでください。

次に、渡されたストリームをオーバーロードで使用します。メソッドでは、引数coutを使用するだけでとにかく使用する場合に使用しstreamます。

私はこれをテストしていませんが、うまくいくかどうかを確認してください。

class sex_t
{
private:
    char __sex__;
public:
    sex_t(char sex_v = 'M'):__sex__(sex_v)
    {
        if (sex_v != 'M' && sex_v != 'F')
        {
            cerr << "Sex type error!" << sex_v << endl;
            __sex__ = 'M';
        }
    }

    friend ostream& operator << (ostream& stream, sex_t& sex);
};


ostream& operator << (ostream& stream, sex_t& sex)
{
    if (__sex__ == 'M')
        stream << "Male";
    else
        stream << "Female";
    return stream;
}
于 2012-06-27T03:17:08.443 に答える