可能であれば、非会員および非友人機能として。
Herb SutterとScott Meyersによって説明されているように、カプセル化を向上させるために、メンバー関数よりも非フレンド非メンバー関数を優先します。
C ++ストリームのように、選択できない場合があり、メンバー以外の関数を使用する必要があります。
ただし、これらの関数をクラスのフレンドにする必要があるという意味ではありません。これらの関数は、クラスアクセサーを通じてクラスにアクセスできます。これらの関数をこの方法で作成することに成功すると、勝利します。
演算子の<<および>>プロトタイプについて
あなたの質問であなたが挙げた例は間違っていると思います。例えば;
ostream & operator<<(ostream &os) {
return os << paragraph;
}
このメソッドがストリームでどのように機能するかを考えることすらできません。
<<演算子と>>演算子を実装する2つの方法を次に示します。
タイプTのストリームのようなオブジェクトを使用するとします。
そして、T型のオブジェクトの関連データを抽出/挿入/挿入したいということです。
ジェネリック演算子の<<および>>関数プロトタイプ
関数としての最初の存在:
// T << Paragraph
T & operator << (T & p_oOutputStream, const Paragraph & p_oParagraph)
{
// do the insertion of p_oParagraph
return p_oOutputStream ;
}
// T >> Paragraph
T & operator >> (T & p_oInputStream, const Paragraph & p_oParagraph)
{
// do the extraction of p_oParagraph
return p_oInputStream ;
}
ジェネリック演算子の<<および>>メソッドのプロトタイプ
2番目はメソッドとして存在します。
// T << Paragraph
T & T::operator << (const Paragraph & p_oParagraph)
{
// do the insertion of p_oParagraph
return *this ;
}
// T >> Paragraph
T & T::operator >> (const Paragraph & p_oParagraph)
{
// do the extraction of p_oParagraph
return *this ;
}
この表記を使用するには、Tのクラス宣言を拡張する必要があることに注意してください。STLオブジェクトの場合、これは不可能です(変更することは想定されていません...)。
そして、TがC ++ストリームの場合はどうでしょうか?
以下は、C ++ストリーム用の同じ<<および>>演算子のプロトタイプです。
汎用的なbasic_istreamおよびbasic_ostreamの場合
ストリームの場合は、C ++ストリームを変更できないため、関数を実装する必要があることに注意してください。それは次のようなものを意味します:
// OUTPUT << Paragraph
template <typename charT, typename traits>
std::basic_ostream<charT,traits> & operator << (std::basic_ostream<charT,traits> & p_oOutputStream, const Paragraph & p_oParagraph)
{
// do the insertion of p_oParagraph
return p_oOutputStream ;
}
// INPUT >> Paragraph
template <typename charT, typename traits>
std::basic_istream<charT,traits> & operator >> (std::basic_istream<charT,traits> & p_oInputStream, const CMyObject & p_oParagraph)
{
// do the extract of p_oParagraph
return p_oInputStream ;
}
char istreamおよびostreamの場合
次のコードは、charベースのストリームでのみ機能します。
// OUTPUT << A
std::ostream & operator << (std::ostream & p_oOutputStream, const Paragraph & p_oParagraph)
{
// do the insertion of p_oParagraph
return p_oOutputStream ;
}
// INPUT >> A
std::istream & operator >> (std::istream & p_oInputStream, const Paragraph & p_oParagraph)
{
// do the extract of p_oParagraph
return p_oInputStream ;
}
Rhys Ulerichさんは、charベースのコードがその上の一般的なコードの「特殊化」に過ぎないという事実についてコメントしました。もちろん、Rhysは正しいです。charベースの例の使用はお勧めしません。読みやすいので、ここでのみ示します。charベースのストリームのみを処理する場合にのみ実行可能であるため、wchar_tコードが一般的なプラットフォーム(Windowsなど)では回避する必要があります。
これがお役に立てば幸いです。