C++で挿入演算子(<<)をオーバーロードしてオブジェクトを出力する方法
C++では、標準出力ストリーム cout を使って自作クラスのオブジェクトを直接表示できるようにするために、挿入演算子(<<)をオーバーロードするのが一般的です。この記事では、氏名情報を持つ Person クラスを例に、その具体的な実装方法をわかりやすく解説します。
課題の概要
まず、f_name(名)と l_name(姓)という2つの文字列属性を持つ Person クラスを考えます。このクラスには、それぞれの値を取得するためのメソッド get_first_name() と get_last_name() が用意されています。
目的は、挿入演算子(<<)をオーバーロードし、cout を使って名前と姓を整形して出力できるようにすることです。
例えば、名が「Sumit」、姓が「Ray」の Person オブジェクトを渡すと、出力は次のようになります。
First name: Sumit, Last name: Ray
解決のための手順
- 挿入演算子のオーバーロードは、クラスの外部で定義します(左辺が
ostreamオブジェクトになるため、メンバ関数にはできません)。 - 戻り値の型は
ostreamへの参照(ostream&)とします。 - 引数には、
ostream参照変数osと、出力対象となるオブジェクトへの参照を受け取ります。 osを使って、オブジェクトの各データを適切な順序で出力します。- 最後に
osを返すことで、cout << p << "..."のような連結出力にも対応できます。
コード例
それでは、実際の実装例を見て理解を深めましょう。
#include <iostream>
using namespace std;
class Person {
private:
string f_name;
string l_name;
public:
Person(string first_name, string last_name) : f_name(first_name), l_name(last_name) {}
string& get_first_name() {
return f_name;
}
string& get_last_name() {
return l_name;
}
};
// 挿入演算子のオーバーロード(クラス外で定義)
ostream& operator<<(ostream& os, Person& p) {
os << "First name: " << p.get_first_name()
<< ", Last name: " << p.get_last_name();
return os;
}
int main() {
Person p("Sumit", "Ray");
// オブジェクトを cout で直接出力できる
cout << p << ", he is our member.";
}
入力
p("Sumit", "Ray")
出力
First name: Sumit, Last name: Ray, he is our member.
実装のポイント
- 非メンバ関数として定義する:
operator<<の左辺はostreamオブジェクトになるため、クラスのメンバ関数として定義できません。クラス外に定義するか、プライベートメンバへアクセスしたい場合はfriend宣言を利用します。 ostream&を返す: ストリームへの参照を返すことで、cout << a << bのように演算子を連ねたチェーン出力が可能になります。const参照を使うとより安全: 出力のみを行う場合は、引数をconst Person& pとすることで、一時オブジェクトも受け取れるようになり、より汎用的な実装になります。
-
C++でクラス名の後にセミコロンを付けると何を意味するのか?前方宣言の役割を解説
C++のクラス名の後にあるセミコロンの意味とは?C++のコードを見ていると、次のような記述を目にすることがあります。class Person;このように、クラス名の直後にセミコロンだけを置いて定義を書かない記述には、実は重要な役割があります。これは「前方宣言(フォワード宣言)」と呼ばれるものです。前方宣言(フォワード宣言)とはclass Person; という記述は、「Person という名前のクラスが存在する」ことをコンパイラに事前に伝えるための宣言です。この宣言があることで、コンパイラはその時点でまだクラスの詳細な定義がなくても、Person という名前を問題なく扱えるようになります。つま
-
C++で単項マイナス演算子をオーバーロードする方法をわかりやすく解説
C++における演算子のオーバーロードとはC++では、operatorキーワードを使って関数を宣言することで、特定の演算子記号がクラスのインスタンスに適用されたときの動作を独自に定義できます。これにより、1つの演算子に複数の意味を持たせることが可能になり、この仕組みを「オーバーロード」と呼びます。コンパイラは、オペランドの型を調べることで、演算子のそれぞれの意味を適切に区別します。単項演算子の種類単項演算子とは、1つのオペランドに対して作用する演算子のことです。代表的な単項演算子には、以下のようなものがあります。インクリメント(++)演算子とデクリメント(--)演算子単項マイナス(-)演算子論理