...ing logging 4.0

はてなブログに移行しました。D言語の話とかいろいろ。

std::cout

後輩が std::cout 知らないとか言うので何がどう便利なのかがわかるようなサンプルを書いてみた.


パッと思いついたメリットは次の2つ.

  • printf では型指定を間違うとクラッシュする問題があったが,std::cout では型を自動認識してくれるためこの問題が起こらない.
  • オブジェクトなので関数やクラスに渡して持ち運びできる.


今回は,2つ目のメリットがわかるようなサンプルコードを示そう.

サンプルコード:

#include <iostream>

class Fruits
{
public:
	virtual void save(std::ostream& out) = 0;
};

class Apple : public Fruits
{
public:
	virtual void save(std::ostream& out)
	{
		out << "リンゴのせーぶだよ!"
			<< std::endl // 改行
			;
	}
};

class Orange : public Fruits
{
public:
	virtual void save(std::ostream& out)
	{
		out << "ミカンのせーぶよ!"
			<< std::endl // 改行
			;
	}
};

void main()
{
	// リンゴくん,ミカンちゃん,こんにちは
	Fruits* one = new Apple;  // <こんにちは
	Fruits* two = new Orange; // <こんにちは

	// あそびのじかんですよー

	//...

	// きょうはここまで
	one->save(std::cout); // せーぶしとこ
	two->save(std::cout); // わたしもー

	// あとかたづけしましょうね
	delete one; // <はーい
	delete two; // <はーい

	// そこ,ぎゃーときこえるとかいわない
}

ディスプレイへの出力結果:

リンゴのせーぶだよ!
ミカンのせーぶよ!

他の関数やクラスに渡して持ち運びできるので,まるで色紙のように,たくさんの人が持ち回って書き込んでいける.
そうすれば,各人に好きなように書き込んでもらうことができて,色紙を渡す側は内容のことは考えなくて済むから,嬉しい.


ちなみに,std::ostream クラスは std::cout の親クラスだと思っていれば,とりあえずは,それでよろしい.
save 関数の中では,(書き込み機能を持った側の)std::ostream 親クラスの << 演算子(という関数) を,子クラスで呼び出している.
ここにオブジェクト指向の基本である多態性が使われている.


std::cout に対して << をすると,ディスプレイ(標準出力)に文字が出力される.
これは,std::cout は標準出力を任せられているクラスだからだ.
オブジェクト指向を勉強していたら気づくかもしれないが,他の出力先を任せられているクラスも用意されている.
例えば;

  • std::ofstream : ファイル出力ストリーム
  • std::ostringstream : 文字列出力ストリーム

これらはすべて std::ostream の子クラスなので,サンプルコードの std::cout の代わりにこれらを使えば,それだけで出力先が変更できて,嬉しい.
そういうこと.