質問をすることでしか得られない、回答やアドバイスがある。

15分調べてもわからないことは、質問しよう!

新規登録して質問してみよう
ただいま回答率
85.48%
C++

C++はC言語をもとにしてつくられた最もよく使われるマルチパラダイムプログラミング言語の1つです。オブジェクト指向、ジェネリック、命令型など広く対応しており、多目的に使用されています。

Q&A

解決済

2回答

3262閲覧

C++ 挿入演算子のオーバーロードの際に、戻り値を参照にする理由

SorasoSukhavati

総合スコア17

C++

C++はC言語をもとにしてつくられた最もよく使われるマルチパラダイムプログラミング言語の1つです。オブジェクト指向、ジェネリック、命令型など広く対応しており、多目的に使用されています。

0グッド

0クリップ

投稿2019/03/28 16:36

疑問点

詳細はソースを見て頂きたいのですが、ざっと説明いたしますと、演算子や++演算子のオーバーロードの際には、戻り値がクラスで問題ないのに、friend関数を用いて<<演算子をオーバーロードする際に、参照の戻り値にする理由がわかりません。

C++

1#include<iostream> 2using namespace std; 3 4class Car 5{ 6 private: 7 int num; 8 double gas; 9 public: 10 Car( int n = 0, double g = 0 ); 11 Car( const Car& c ); 12 void setCar( int n, double g ); 13 void show(); 14 //friend ostream operator<<( ostream& out, Car c ); //エラー 15 friend ostream& operator<<( ostream& out, Car c ); 16}; 17 18Car::Car( int n, double g ) 19{ 20 num = n; 21 gas = g; 22} 23 24Car::Car( const Car& c ) 25{ 26 num = c.num; 27 gas = c.gas; 28} 29 30void Car::setCar( int n, double g ) 31{ 32 num = n; 33 gas = g; 34} 35 36void Car::show() 37{ 38 cout << "Num: " << num << endl; 39 cout << "Gas: " << gas << endl; 40} 41 42//ostream operator<<( ostream& out, Car c ) 43//{ 44// out << "num: " << c.num << " gas: " << c.gas << endl; 45// return out; 46//} 47 48ostream& operator<<( ostream& out, Car c ) 49{ 50 out << "num: " << c.num << " gas: " << c.gas << endl; 51 return out; 52} 53 54int main() 55{ 56 Car mycar( 1234, 25.5 ); 57 58 cout << mycar; 59/* 60この処理で、挿入演算子がどのように処理されるのかが疑問。 61例えば、<<演算子は、operator<<(cout,mycar)という関数を呼び出すことと同じ意味だとするなら 62戻り値がostreamクラスの参照となっているので、どこかにその参照が格納されているのかという疑問 63 64どこにも戻り値が格納されていないのならば、&をつけないことで何故エラーが出てしまうのかという疑問 65*/ 66 67 return 0; 68}

コメントで疑問を書いてしまいましたが、ご教授いただければ幸いです。
よろしくお願いします。

気になる質問をクリップする

クリップした質問は、後からいつでもMYページで確認できます。

またクリップした質問に回答があった際、通知やメールを受け取ることができます。

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

guest

回答2

0

ベストアンサー

こんにちは。

std::ostreamのインスタンスはコピーできません。(I/Oの状態を管理している変数がコピーされると実I/Oと管理領域の値に不整合が発生するので、それを避けるためにこのような設計になっています。)
戻り値を値型にするとreturnする際にコピーされるのでエラーになります。

戻り値がostreamクラスの参照となっているので、どこかにその参照が格納されているのかという疑問

std::coutはグローバル領域に確保されています。
std::ostream ofs("ファイル名");のようにして確保すると、このofsとして確保されていますので、禁忌(ローカル変数として確保したものをポインタや参照で返却するなど)を侵さない限り寿命が不正に尽きることは普通はないです。

投稿2019/03/28 16:42

Chironian

総合スコア23272

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

SorasoSukhavati

2019/03/28 18:24

ご回答ありがとうございました。 試しに戻り値をvoidとしてオーバーロードをしてみたところ正しく動きました。 より理解が深まり、とても勉強になりました。
guest

0

cout << a << b は (cout << a) << b と解釈されます。
なので (cout << a) が ostream& を返さないと 後続する << b ができなくなるです。

投稿2019/03/30 02:10

episteme

総合スコア16614

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

あなたの回答

tips

太字

斜体

打ち消し線

見出し

引用テキストの挿入

コードの挿入

リンクの挿入

リストの挿入

番号リストの挿入

表の挿入

水平線の挿入

プレビュー

15分調べてもわからないことは
teratailで質問しよう!

ただいまの回答率
85.48%

質問をまとめることで
思考を整理して素早く解決

テンプレート機能で
簡単に質問をまとめる

質問する

関連した質問