独自クラスをストリーム出力に対応させる - C++ プログラミング
PROGRAM
独自クラスをストリーム出力に対応させる
C++ では std::ostream などのストリームを使って、さまざまなデータ型の値をストリーム挿入演算子 (<<) をつかって統一的にデータを出力できるようになっています。
独自に実装したクラスでも、それを右辺に扱うストリーム挿入演算子 (<<) をグローバルスコープでオーバーロードしておけば、独自クラスの値をそのまま挿入演算子 (<<) に指定できるようになります。
準備
ストリーム挿入演算子のオーバーロードでは、左辺に std::ostream 型を指定する必要があるため、あらかじめ <iostream> ヘッダーをインクルードしておきます。
#include <iostream>
ストリーム挿入演算子を実装する
出力ストリームにクラスの値を出力できるように、ストリーム挿入演算子 (<<) を定義します。
たとえば CMyClass というクラス型の変数をストリーム挿入演算子 (<<) に直接指定できるようにするには、そのクラス内ではなくて外側に "operator<<" のオーバーライドを定義します。
このとき、第一引数には std::ostream 型の参照を、第二引数に CMyClass 型の参照を、それぞれ指定するようにします。
class CMyClass
{
};
// 扱う値は第二引数に指定します。また、連続してストリーム出力できるように、戻り値では第一引数で受け取ったストリームを返します。
std::ostream& operator<<(std::ostream& stream, const CMyClass& value);
このように定義したら、実装では、第一引数で受け取ったストリームに対して、たとえばクラスの内容を文字列データに変換した値を出力するように実装します。
std::ostream& operator<<(std::ostream& stream, const CMyClass& value)
{
// 実装されている何らかの方法で、クラスの値をデータに変換します。
const char* stringValue = value.toString();
// 取得したデータをストリームに出力します。
stream << stringValue;
// 呼び出し元で引き続きストリーム出力できるように、受け取ったストリームをそのまま返します。
return stream;
};
これで、ストリーム挿入演算子 (<<) を使ってクラスの値をダイレクトにストリーム出力できるようになりました。
このとき、ストリーム挿入演算子の実装は、クラスの実装とは違うところでやっているので、そのままだとクラス内の private メンバにアクセスすることができません。
クラスの値をデータ出力する上で private メンバにアクセスする必要がある場合には、クラスの定義の中で、このストリーム挿入演算子を friend 指定しておくようにします。
class CMyClass
{
friend std::ostream& operator<<(std::ostream&, const CMyClass&);
};
こうしておけば、グローバルスコープに定義したストリーム挿入演算子からこのクラスの private メンバにアクセスできるようになるので、柔軟なデータ抽出処理をプログラムできるようになります。
[ もどる ]