独自クラスをストリーム出力に対応させる - 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 メンバにアクセスできるようになるので、柔軟なデータ抽出処理をプログラムできるようになります。


[ もどる ]