ここから本文です

C++の単項演算子のオーバーロードについて質問です。

rin********さん

2019/6/612:16:53

C++の単項演算子のオーバーロードについて質問です。

以下のプログラムの単項演算子のオーバーロードのメンバ関数の返り値に*Thisが設定されており、自身のポインタを返すようになっていますが、なぜでしょうか?
main()で参照を使っているため、return *thisがあってもなくても結果は変わらないです。coord型は返り値ありなため、そのまま書いているだけなのでしょうか?

ご回答よろしくお願いします。


#include <iostream>
using namespace std;

class coord {
____int x, y;
public:
____coord() {
________x = 0;
________y = 0;
____}
____coord( int i, int j ) {
________x = i;
________y = j;
____}
____void get_xy( int &i, int &j ) {
____i = x;
____j = y;
____}
____coord operator+( coord ob2 );
____coord operator+( int i );
____coord operator++();
____coord operator++( int notused );
};

coord coord::operator+( coord ob2 ) {
____coord tmp;
____tmp.x = x + ob2.x;
____tmp.y = y + ob2.y;

____return tmp;
}

coord coord::operator+( int i ) {
____coord temp;
____temp.x = x + i;
____temp.y = y + i;

____return temp;
}

coord coord::operator++() {
____x++;
____y++;
____return *this;
}
coord coord::operator++( int notused ) {
____x++;
____y++;
____return *this;
}

int main() {
____coord o1( 3, 9 ), o2( 8, 31 ), o3;
____int x, y;

____o1.get_xy( x, y );
____cout << " o1 | " << "x: " << x << ", y: " << y << endl;

____o2.get_xy( x, y );
____cout << " o2 | " << "x: " << x << ", y: " << y << endl;

____o3 = o1 + o2;
____o3.get_xy( x, y );
____cout << " o3 (o1+o2) | " << "x: " << x << ", y: " << y << endl;

____++o3;
____o3.get_xy( x, y );
____cout << " ++o3 | " << "x: " << x << ", y: " << y << endl;

____o3++;
____o3.get_xy( x, y );
____cout << " o3++ | " << "x: " << x << ", y: " << y << endl;

____o3 = o3 + 5;
____o3.get_xy( x, y );
____cout << " o3+5 | " << "x: " << x << ", y: " << y << endl;

____return 0;
}

補足実行結果は以下のようになります。

o1 | x: 3, y: 9
o2 | x: 8, y: 31
o3 (o1+o2) | x: 11, y: 40
++o3 | x: 12, y: 41
o3++ | x: 13, y: 42
o3+5 | x: 18, y: 47
o1++ | x: 4, y: 10

この質問は、男性に回答をリクエストしました。

閲覧数:
86
回答数:
4
お礼:
500枚

違反報告

ベストアンサーに選ばれた回答

prw********さん

2019/6/613:00:34

>単項演算子のオーバーロードのメンバ関数の返り値に*This

こういうパズルめいた厭らしい書法を考えます

ほとんど難癖や因縁ですが、合法な書き方です

o3 = o1++ + ++o1;
o3 = (o1++) + (o2++);
o3 = ((o1++)++)++;
o3 = ((o1++)+(o2++))++ + o1;

返信を取り消しますが
よろしいですか?

  • 取り消す
  • キャンセル

「オーバーロード」の検索結果

検索結果をもっと見る

ベストアンサー以外の回答

1〜3件/3件中

並び替え:回答日時の
新しい順
|古い順

kon********さん

2019/6/705:53:42

coord coord::operator++()
が定義されている以上
coord coord::operator++( int notused ) {
coord temp=*this;
x ++;y ++;
return temp;
}
のほうが良いのではないかと思います。

このように別に*thisで返す必要性がある
わけでもありません。
演算子のオーバーロードと言えども実質的に
関数定義みたいなものなので普通のcoordを返す
関数と同じくcoord型の値を返せばよいわけです

leh********さん

2019/6/622:41:41

> 以下のプログラムの単項演算子のオーバーロードのメンバ関数の
> 返り値に*Thisが設定されており、自身のポインタを返すように
> なっていますが、なぜでしょうか?
違いますよ。
自身のポインタを返しているのではなく、自身のインスタンスを
返しているんですよ。
自身のポインタを返すのであれば return this です。
さらに正確にいえば
coord coord::operator++() {
  x++;
  y++;
  return *this;
}
では *this のコピーを返しています。
#コピーコンストラクタが *this の一時オブジェクトを生成します。
ただし、他の方が説明されているように
coord& coord::operator++() {
  x++;
  y++;
  return *this;
}
とすべきです。
何故かといえば、前置インクリメント演算子は C と C++ では規格が
違うからです。
C では ++a も a++ も式の評価結果は右辺値です。
対して C++ では a++ の式の評価結果は右辺値ですが ++a の式の
評価結果は左辺値です。
そのため独自の class における前置インクリメント演算子のオーバー
ロードでも左辺値(自身のインスタンス)を返すべきです。

あと
coord coord::operator+(int i) {
  coord temp;
  temp.x = x + i;
  temp.y = y + i;
  return temp;
}
は、ダメ実装の典型ですよ。
これでは
o3 = o3 + 5; // o3 = o3.operator+(5);
は演算可能でも
o3 = 5 + o3; // o3 = 5.operator+(o3); はできない
は演算不可能になってしまいますね。

プロフィール画像

カテゴリマスター

n2q********さん

2019/6/617:42:57

int i = 0;
++ ++ i;
cout << i << std::endl;

これで i は 2 になります。++ が2回適用される形です。


coord j;
++ ++ j;
j.get_xy( x, y );
cout << x << ", " << y << std::endl;

2, 2 となって欲しいところですが…


2か所直しますよ。

(1)21行目

【修正前】coord operator++();
【修正後】coord& operator++();


(2)41行目

【修正前】coord coord::operator++() {
【修正後】coord& coord::operator++() {



『返り値に*thisが設定されており、自身のポインタを返すようになっていますが、なぜでしょうか?』

代入演算子(= や += など)の場合と同じなのですが、左辺値を返すことが必要なためです。

int a;
(a = 10) += 5;

こうすると a には 15 が設定されます。(a = 10)のところの型が int& だからです。


struct sample {
int a;
sample& operator=(int n)
{
a = n;
return *this;
}
sample& operator+=(int n)
{
a += n;
return *this;
}
};

sample x;
(x = 10) += 5;

これを実現するために = の戻り値の型を sample& として、return *this; としているわけです。


これは前置の ++ に関しても同様となります。

みんなで作る知恵袋 悩みや疑問、なんでも気軽にきいちゃおう!

別のキーワードで検索:

Yahoo! JAPANは、回答に記載された内容の信ぴょう性、正確性を保証しておりません。
お客様自身の責任と判断で、ご利用ください。
本文はここまでです このページの先頭へ

「追加する」ボタンを押してください。

閉じる

※知恵コレクションに追加された質問は選択されたID/ニックネームのMy知恵袋で確認できます。

不適切な投稿でないことを報告しました。

閉じる