🎄teratailクリスマスプレゼントキャンペーン2024🎄』開催中!

\teratail特別グッズやAmazonギフトカード最大2,000円分が当たる!/

詳細はこちら
C

C言語は、1972年にAT&Tベル研究所の、デニス・リッチーが主体となって作成したプログラミング言語です。 B言語の後継言語として開発されたことからC言語と命名。そのため、表記法などはB言語やALGOLに近いとされています。 Cの拡張版であるC++言語とともに、現在世界中でもっとも普及されているプログラミング言語です。

C++

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

Q&A

解決済

3回答

3533閲覧

C++で演算子オーバーロードを行う方法がわかりません

Magolors

総合スコア21

C

C言語は、1972年にAT&Tベル研究所の、デニス・リッチーが主体となって作成したプログラミング言語です。 B言語の後継言語として開発されたことからC言語と命名。そのため、表記法などはB言語やALGOLに近いとされています。 Cの拡張版であるC++言語とともに、現在世界中でもっとも普及されているプログラミング言語です。

C++

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

0グッド

0クリップ

投稿2019/12/15 10:03

前提・実現したいこと

演算子オーバーロードによってクラス同士の二項演算を定義したいのですが、どうしてもエラーが出ます。引数、戻り値ともにクラスにするにはどうすればよいのでしょうか。関数にするなど他に方法はあると思うのですが、そうではなく演算子のオーバーロードによって実現する方法を知りたいです。非常に初歩的な質問で申し訳ありませんが、どなたかご教授願います。

発生している問題・エラーメッセージ

Overloaded 'operator+' must be a unary or binary operator (has 3 parameters)

該当のソースコード

C++

1#include <iostream> 2using namespace std; 3 4class test{ 5 int d; 6 int MOD; 7 8 public: 9 10 test(int i, int M){ 11 d = i; 12 MOD = M; 13 } 14 15 test operator+(test &t1, test &t2){ 16 return test((t1.d + t2.d) % t1.MOD, t1.MOD); 17 } 18}; 19 20int main(){ 21 cout << test(3, 2) + test(5, 2) << endl; 22}

試したこと

引数など変更しましたが、わかりませんでした。

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

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

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

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

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

jimbe

2019/12/15 10:17

エラーメッセージをネットで検索してみては如何でしょうか.
Magolors

2019/12/15 10:30

検索したのですが、わからなかったのでこのサイトに投稿しました。初歩的な質問で申し訳ありません。
guest

回答3

0

質問のような事例では majiponi 氏の解で十分なので余談になりますが、メンバ関数として定義した二項演算子は左辺では暗黙の型変換が働かず右辺では暗黙の型変換が働きます。

cpp

1#include <iostream> 2 3class test { 4 int d; 5 int MOD; 6 7public: 8 test(int i, int M); 9 test operator+(const test&); 10 friend std::ostream& operator<<(std::ostream&, const test&); 11}; 12 13test::test(int i, int M) : d(i), MOD(M) {} 14 15test test::operator+(const test& t) { 16 return test((this->d + t.d) % this->MOD, this->MOD); 17} 18 19std::ostream& operator<<(std::ostream &os, const test &a) { 20 return os << a.d << " " << a.MOD; 21} 22 23// test に変換可能な test2 型 24class test2 { 25public: 26 operator test(void) { 27 return test(10, 10); 28 } 29}; 30 31int main(void) { 32 // + の右辺が test2 型なのは OK 33 std::cout << test(3, 2) + test2() << std::endl; 34 35 // + の左辺が test2 型なのはエラーになる。 36 std::cout << test2() + test(3, 2) << std::endl; 37 return 0; 38}

このような非対称は好ましくないので既存の (引数として与えられた) オブジェクトを変更せずにあたらしいオブジェクトを生成する二項演算子に関しては非メンバ関数としてオーバーロードするのが好ましいと考えられています。 (標準ライブラリもそうなってます。)

cpp

1#include <iostream> 2 3class test{ 4 int d; 5 int MOD; 6 7public: 8 test(int i, int M); 9 friend test operator+(const test&, const test&); 10 friend std::ostream& operator<<(std::ostream&, const test&); 11}; 12 13test::test(int i, int M) : d(i), MOD(M) {} 14 15test operator+(const test& t1, const test& t2) { 16 return test((t1.d + t2.d) % t1.MOD, t1.MOD); 17} 18 19std::ostream& operator<<(std::ostream &os, const test &a) { 20 return os << a.d << " " << a.MOD; 21} 22 23// test に変換可能な test2 型 24class test2 { 25public: 26 operator test(void) { 27 return test(10, 10); 28 } 29}; 30 31int main(void) { 32 // + の右辺が test2 型なのは OK 33 std::cout << test(3, 2) + test2() << std::endl; 34 // + の左辺が test2 型なのも OK 35 std::cout << test2() + test(3, 2) << std::endl; 36 return 0; 37}

投稿2019/12/15 11:09

SaitoAtsushi

総合スコア5684

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

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

0

C++

1 2#include <iostream> 3using namespace std; 4 5class test{ 6 int d; 7 int MOD; 8 9 public: 10 11 test(int i, int M){ 12 d = i; 13 MOD = M; 14 } 15 16 test operator+(test t){ 17 return test((this->d + t.d) % this->MOD, this->MOD); 18 } 19 20 friend std::ostream& operator<<(std::ostream&, const test&); 21}; 22 23std::ostream& operator<<(std::ostream &strm, const test &a) { 24 return strm << a.d << " " << a.MOD; 25} 26 27int main(){ 28 cout << test(3, 2) + test(5, 2) << endl; 29 return 0; 30}

type operator operator-symbol ( parameter-list )
parameter-list には、2項目のオペランドを受け取ります

らしいので、そこの修正と、testクラスを出力できるよう>>も
オーバーライドしました。プライベートメンバにアクセスするため
フレンド関数も追加しました。

[参考]
http://wisdom.sakura.ne.jp/programming/cpp/cpp27.html
https://stackoverflow.com/questions/1549930/c-equivalent-of-javas-tostring

投稿2019/12/15 10:30

otaks

総合スコア223

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

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

Magolors

2019/12/15 10:38

ありがとうございます。
guest

0

ベストアンサー

C++

1class test{ 2 int d; 3 int MOD; 4 5 public: 6 7 test(int i, int M){ 8 d = i; 9 MOD = M; 10 } 11 12 test operator+(test &another){ 13 return test((d + another.d) % MOD, MOD); 14 } 15};

クラスのメンバ関数として+演算子を定義する場合、左側の項は自分自身を使います。

投稿2019/12/15 10:18

majiponi

総合スコア1722

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

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

Magolors

2019/12/15 10:29

ありがとうございました。
guest

あなたの回答

tips

太字

斜体

打ち消し線

見出し

引用テキストの挿入

コードの挿入

リンクの挿入

リストの挿入

番号リストの挿入

表の挿入

水平線の挿入

プレビュー

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

ただいまの回答率
85.36%

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

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

質問する

関連した質問