4

独学でC++を学んでいます。演算子のオーバーロードを勉強していて、加算と減算の演算子のオーバーロードを理解することができました。しかし、I/O 演算子のオーバーロードは少し混乱します。複素数のクラスを作成しましたが、演算子をオーバーロードしています。

Complex.h の関数プロトタイプ

friend ostream& operator<<(ostream&, const Complex&);

Complex.cpp の関数

ostream& operator<<(ostream& os, const Complex& value){
os << "(" << value.r <<", "
<< value.i << ")" ;
return os;
}
  1. ここでフレンド関数宣言を使用する必要がある理由を (基本的なレベルで) 誰でも説明できますか?
  2. すべての引数と演算子の戻り値の型を参照渡しする必要があるのはなぜですか?
  3. この関数は const を使用しなくても問題なく動作しますが、なぜここで const を使用するのでしょうか。Complex を定数参照として渡す利点は何ですか?
4

6 に答える 6

3

ストリーミング オペレーターをフレンドにする必要はありませんComplex オブジェクトは演算子の右側にあるため、外部で宣言する必要があります

ただし、Complex クラスに (おそらく getter を介して) 必要なメンバーにアクセスする方法がある場合は、ストリーミング オペレーターにそれらを使用させることができます。言う:

std::ostream& operator<<( std::ostream& os, Complex const& cpx )
{
   return os << cpx.getReal() << ',' << cpx.getImaginary();
}

オーバーoperator/ロードは内部関数として実行できますが、実際には 2 つの const& パラメーターを持つ外部関数として実装する方が適切です。メンバー関数の場合は、const メンバーである必要があります。あなたのものではありません。

あなたはそれに基づいてそれを実装するかもしれませoperator /=

Complex operator/ ( Complex const& lhs, Complex const& rhs )
{
    Complex res( lhs );
    res /= rhs; // or just put return in front of this line
    return res; 
}
于 2014-07-13T14:39:38.217 に答える
2

の場合friend ostream& operator<<(ostream&,const Complex&);:

  1. Complexここでフリー関数を宣言し、オブジェクトの内部 (プライベート/保護) にアクセスしたいためです。これらのオーバーロードに「フレンド フリー関数」を使用することは非常に一般的ですが、必須ではありません。

  2. ストリームはコピーできないため (意味がありません。この投稿も参照してください)、値渡しにはコピーが必要です。値渡しComplexには、役に立たないコピーも必要です。

  3. これらの出力演算子は、作業中のオブジェクトを変更することは想定されていないため (入力演算子は明らかに)、それconstを確実にするために追加します。

于 2014-07-13T13:51:24.763 に答える
1
  1. ここでフレンド関数宣言を使用する必要がある理由を (基本的なレベルで) 誰でも説明できますか?

    クラスを別のクラスとして宣言する場合friend of、フレンド クラスがクラスのプライベートおよび保護された属性と関数にアクセスできることを意味します。
    あなたの場合ostream& operator<<、フレンドとして宣言します。これは、その関数の本体内で、ostream クラスが複雑なクラスのプライベートおよび保護された関数と属性にアクセスできることを意味します。

  2. すべての引数と演算子の戻り値の型を参照渡しする必要があるのはなぜですか?

    ostream オブジェクトのコピーを作成することを回避するために、そのように記述されているためです。したがって、<<オーバーロードは、使用するたびにコピーを作成せずに同じオブジェクトを使用します。

  3. この関数は const を使用しなくても問題なく動作しますが、なぜここで const を使用するのでしょうか。Complex を定数参照として渡す利点は何ですか?

    const関数の後は、クラスの属性を変更していないことを意味します。

それはほぼ正しいと思いますし、お役に立てば幸いですが、コメントしたい方はお気軽に。

于 2014-07-13T13:51:30.933 に答える
0
friend ostream& operator<<(ostream&, const Complex&);

ここでは、complex のプライベート メンバーにアクセスできるようにする必要があるため、関数はフレンドである必要があります。

クラスをオーバーロードする場合、オーバーロードされた関数でクラスのデータ メンバーにアクセスする必要があり、データ メンバーがプライベートである可能性があり<<ますComplexComplexそれらがプライベートである場合、データメンバーにアクセスするには、それをクラスoperator <<のメンバーにする必要があります。complexこれは、オペレーターの左側のオブジェクトがostreamクラスタイプであるため、唯一のオプションは、それをフレンドにComplexしてオーバーロード<<することですグローバルスコープ機能。

他の人から言われたように、オブジェクトの複数のコピーが作成されるのを避けるために、オブジェクトは参照によって返されるようになりました。そして、オペレーターが `cout< のようなカスケード書き込みに使用しているときにサポートするため、オブジェクトを返す必要があります。

引数は として渡されます。これは、オブジェクトが関数の側で変更されないかconstのようにオブジェクトを受け取ることが常に良い方法であるためです。constこれにより、オブジェクトでも機能しconstます。

于 2014-07-13T13:52:40.080 に答える