第22章 出力ストリーム


さて、今まで何気なく使っていたcout についてみてみましょう。 第1章では、coutは関数ではなく、変数みたいものと いい加減な 説明をしてきました。一体これは何なのでしょう。

実はこれは、ostreamクラスのオブジェクトなのです。

(VC++では正確には、ostream_withassignクラス) また、これと一緒に使う「<<」は、オーバー・ロードされた演算子なのです。 演算子のオーバー・ロードについては第16章ですでに説明しました。 本来の演算子「<<」については、C言語編第40章を 参照して下さい。また、「<<」は、

cout << a << "xxx" << endl;

というように連続して使うことができました。 どんどん差し込んでいっているように見えるので「差込演算子」(insertion operator) とも呼ばれます。

では、オペレーター・オーバーロードのところでやったようにこの演算子に ユーザーが勝手に新しい定義を付け足してもよいのでしょうか。

はい。できます。しかし、うまく定義しないと上の例のように 次々と差込ができなくなってしまいます。

うーん、どうすりゃいいの。何か難しそうだな・・・

はい。まともに考えると大変難しいです。しかし昔から決まったやり方があります。 「猫でもわかる」式に覚えてしまいましょう。

ostream& operator << (ostream& o, const T& t);

のように定義します。ある型(もちろんクラスも含みます)Tについての 差込演算子の定義の仕方です。「&」に注意して下さい。これは参照です。 理屈はともかく、実際の例を見てみましょう。例題は、 平面の座標を表すクラスxy_position(筆者が勝手に考えたクラス) について差込演算子の定義を作ってみましょう。

これは、ほぼ決まった書き方です。メンバ関数のX(),Y()の後ろに constがついていることに注意して下さい。これは、 第13章を参照して下さい。 演算子定義のところでconst xy_position& pとしているので 必要なのですね。この定義で<<は( , )と出力するよう定義しています。

はい、新しい差込演算子を実行するとこうなりました。

「あれー?よく見ると変だな」と言っている人はいませんか。 一つは、参照の表し方ですね。第6章では

int &a = b;

のように書き表しました。しかし、

int& a = b;

と書いても同じことです。
もう一つは、オペレーターオーバーロードのやり方ですね。 第16章では、次のような感じで 説明しました。

class Xのオブジェクトaに対して a + b の演算を a.function(b)  のような感じで解説しました。

しかし、当然のことながらfunction(a, b)と いう考え方もできますね。この場合ちょっとした注意が必要です。 functionはフレンド関数でなくてはいけません。 どうして、フレンド関数でなくてはいけないって?ちょっと考えてみて下さい。


[C++Index] [総合Index] [Previous Chapter] [Next Chapter]

Update Feb/04/1997 By Y.Kumei
当ホーム・ページの一部または全部を無断で複写、複製、 転載あるいはコンピュータ等のファイルに保存することを禁じます。