Oracle® Solaris Studio 12.4: C++ ユーザーズガイド

印刷ビューの終了

更新: 2014 年 12 月
 
 

13.3.1 iostream を使用した出力

iostream を使用した出力は、通常、左シフト演算子 (<<) を多重定義したもの (iostream の文脈では挿入演算子といいます) を使用します。ある値を標準出力に出力するには、その値を定義済みの出力ストリーム cout に挿入します。たとえば、someValue を出力するには、次の文を標準出力に挿入します。

cout << someValue;

挿入演算子は、すべての組み込み型について多重定義されており、someValue の値は適当な出力形式に変換されます。たとえば someValuefloat 型の場合<< 演算子はその値を数字と小数点の組み合わせに変換します。float 型の値を出力ストリームに挿入するときは、<< を float 型挿入子といいます。一般に X 型の値を出力ストリームに挿入するときは、<<X 型挿入子といいます。出力形式とその制御方法については、ios(3CC4) のマニュアルページを参照してください。

iostream ライブラリはユーザー定義型をサポートしません。出力する型を独自の方法で定義する場合、型を正しく処理するための挿入子を定義する (つまり、<< 演算子を多重定義する) 必要があります。

<< 演算子は反復使用できます。2 つの値を cout に挿入するには、次の例のような文を使用できます。

cout << someValue << anotherValue;

前述の例では、2 つの値の間に空白が入りません。空白を入れる場合は、次のようにします。

cout << someValue << " " << anotherValue;

<< 演算子は、組み込みの左シフト演算子と同じ優先順位を持ちます。ほかの演算子と同様に、括弧を使用してアクションの順序を指定できます。必要に応じて、優先順位の問題を回避するために括弧を使用します。次の 4 つの文のうち、最初の 2 つは同じ結果になりますが、あとの 2 つは異なります。

cout << a+b;              // + has higher precedence than <<
cout << (a+b);
cout << (a&y);            // << has precedence higher than &
cout << a&y;            // probably an error: (cout << a) & y

13.3.1.1 ユーザー定義の挿入演算子

次のコーディング例では string クラスを定義しています。

#include <stdlib.h>
#include <iostream.h>


class string {
private:
    char* data;
    size_t size;

public:
    // (functions not relevant here)

    friend ostream& operator<<(ostream&, const string&);
    friend istream& operator>>(istream&, string&);
};

この例では、string クラスのデータ部が private であるため、挿入演算子と抽出演算子をフレンド定義しておく必要があります。

ostream& operator<< (ostream& ostr, const string& output)
{    return ostr << output.data;}

次の例は、string とともに使用される多重定義された operator<< の定義です。

cout << string1 << string2;

operator<< は、最初の引数として ostream& (ostream への参照) を受け取り、同じ ostream を返します。このため、次のように 1 つの文で挿入演算子を続けて使用できます。

13.3.1.2 出力エラーの処理

operator<< を多重定義するときは、iostream ライブラリからエラーが通知されることになるため、特にエラー検査を行う必要はありません。

エラーが起こると、エラーの起こった iostreamエラー状態になります。その iostream の状態の各ビットが、エラーの大きな分類に従ってセットされます。iostream で定義された挿入子がストリームにデータを挿入しようとしても、そのストリームがエラー状態の場合はデータが挿入されず、iostream の状態も変わりません。

一般的なエラー処理方法は、メインのどこかで定期的に出力ストリームの状態を検査する方法です。エラーが存在する場合は、何らかの方法でエラーを処理するようにしてください。この章では、文字列を取得してプログラムを異常終了する関数 error を定義したと仮定します。error は事前定義関数 ではありません。入力エラーの処理 関数の例については、Handling Input Errorsを参照してください。iostream の状態を演算子 ! で確認でき、これは iostream がエラー状態の場合にゼロ以外の値を返します。例:

if (!cout) error("output error");

エラーを調べるにはもう 1 つの方法があります。ios クラスでは、operator void *() が定義されており、エラーが起こった場合は NULL ポインタを返します。次の例のような文を使用できます。

if (cout << x) return; // return if successful

また、次のように ios クラスのメンバー関数 good を使用することもできます。

if (cout.good()) return; // return if successful

エラービットは次のような列挙型で宣言されています。

enum io_state {goodbit=0, eofbit=1, failbit=2,
badbit=4, hardfail=0x80};

エラー関数の詳細については、iostream のマニュアルページを参照してください。

13.3.1.3 フラッシュ

多くの入出力ライブラリと同様、iostream も出力データを蓄積し、より大きなブロックにまとめて効率よく出力します。出力バッファーをフラッシュする場合、次のように特殊な値 flush を挿入するだけでフラッシュできます。例:

cout << "This needs to get out immediately." << flush;
 

flush は、マニピュレータと呼ばれるタイプのオブジェクトの 1 つです。マニピュレータを iostream に挿入すると、その値が出力されるのではなく、何らかの効果が引き起こされます。これらの値は実際には関数で、引数 ostream& または istream& 引数を取り、何らかのアクションを実行したあとにその引数を返します (マニピュレータを参照してください)。

13.3.1.4 バイナリ出力

ある値をバイナリ形式のままで出力するには、次の例のようにメンバー関数 write を使用します。次の例では、x の値がバイナリ形式のまま出力されます。

cout.write((char*)&x, sizeof(x));

この例では、&xchar* に変換しており、型変換の規則に反します。通常このようにしても問題はありませんが、x の型が、ポインタまたは仮想メンバー関数を持つクラスであるか、重要なコンストラクタ動作を要求するクラスの場合、前述の例で出力した値を正しく読み込むことができません。