ストリーム演算子
CoddyのC++ジャーニー「オブジェクト指向プログラミング」セクションの一部 — レッスン 43/104。
ストリーム挿入(<<)および抽出(>>)演算子を使用すると、std::cout や std::cin でカスタムクラスを使用できるようになります。これまでに説明した演算子とは異なり、左オペランドがクラスではなくストリームであるため、これらは非メンバ関数として実装する必要があります。
class Point {
int x, y;
public:
Point(int x, int y) : x(x), y(y) {}
// プライベートメンバにアクセスするためにfriendとして宣言します
friend std::ostream& operator<<(std::ostream& os, const Point& p);
friend std::istream& operator>>(std::istream& is, Point& p);
};
std::ostream& operator<<(std::ostream& os, const Point& p) {
os << "(" << p.x << ", " << p.y << ")";
return os;
}
std::istream& operator>>(std::istream& is, Point& p) {
is >> p.x >> p.y;
return is;
}両方の演算子はストリームへの参照を返すため、std::cout << p1 << p2 のようなチェイニングが可能です。挿入演算子はデータを読み取るだけなのでオブジェクトを const 参照で受け取りますが、抽出演算子はオブジェクトを変更するため非 const 参照を受け取ります。
これで、Point をストリームで自然に使用できるようになります。
Point p(3, 4);
std::cout << "Location: " << p << std::endl; // 出力: Location: (3, 4)
Point p2(0, 0);
std::cin >> p2; // 2つの整数を p2 に読み込むチャレンジ
簡単ストリーム演算子のオーバーロードを通じて、std::cout や std::cin でシームレスに使用できる Temperature クラスを作成しましょう。これは、温度を読みやすい形式で表示したり、入力から自然に読み取ったりしたい場合に実用的なシナリオです。
コードを整理するために、2つのファイルを作成します。
Temperature.h: 温度の値(double型)と単位ラベル(char型、摂氏の場合は'C'、華氏の場合は'F')を保持するTemperatureクラスを定義します。クラスには以下のものを含めてください。- 温度の値と単位のためのプライベートメンバ
- 0.0 摂氏に初期化するデフォルトコンストラクタ
- 値と単位を受け取る引数付きコンストラクタ
- ゲッター
getValue()およびgetUnit()(どちらも const) - ストリーム挿入(
<<)および抽出(>>)演算子のフレンド宣言
ストリーム演算子を非メンバ関数として実装します。
- 挿入演算子は、温度を
VALUE UNITの形式(例:25.5 Cや77.9 F)で出力する必要があります。値には小数点以下1桁を使用してください。 - 抽出演算子は、ストリームから値と単位文字を読み取り、それらを Temperature オブジェクトに格納する必要があります。
どちらの演算子も、連鎖(チェイニング)を可能にするためにストリームへの参照を返す必要があります。
main.cpp: 入力から2つの温度を読み取ります。各温度は、value unitの形式(例:25.5 C)で別々の行に指定されます。抽出演算子を使用して
std::cinから読み取り、2つのTemperatureオブジェクトを作成します。次に、挿入演算子を使用して以下の形式で出力します。Temperature 1: <temp1> Temperature 2: <temp2>例えば、入力が以下の場合:
25.5 C 98.6 F出力は以下のようになります:
Temperature 1: 25.5 C Temperature 2: 98.6 F
温度の値を正確に小数点以下1桁でフォーマットするために、<iomanip> の std::fixed と std::setprecision(1) を使用してください。ヘッダーファイルにはインクルードガードを忘れずに追加してください。
自分で試してみよう
#include <iostream>
#include "Temperature.h"
int main() {
// TODO: 2つのTemperatureオブジェクトを作成する
// TODO: 抽出演算子 (>>) を使用して、std::cinから2つの温度を読み取る
// TODO: 挿入演算子 (<<) を使用して温度を出力する
// 形式:
// Temperature 1: <temp1>
// Temperature 2: <temp2>
return 0;
}このレッスンには短いクイズがあります。レッスンを始めて解答し、進捗を記録しましょう。
オブジェクト指向プログラミングのすべてのレッスン
3コンストラクタとデストラクタ
デフォルトコンストラクタ引数付きコンストラクタコピーコンストラクタムーブコンストラクタコンストラクタ初期化リスト委譲コンストラクタデストラクタ詳解Rule of Three / Five / Zeroまとめ - Stringクラス6演算子オーバーロード
演算子オーバーロード入門算術演算子のオーバーロード比較演算子のオーバーロードストリーム演算子代入演算子のオーバーロード[] と () 演算子のオーバーロード型変換演算子まとめ:Matrix クラス