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

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

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

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

Q&A

解決済

1回答

816閲覧

演算子オーバーロードの具体的な動作が分かりません

yukziaru2587

総合スコア1

C++

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

0グッド

0クリップ

投稿2022/11/30 02:40

編集2022/11/30 03:21

前提

c++の勉強をしている初心者です。以下のソースコードはサンプルコードなのですが、2つ疑問点があります。ご教授お願いしたいです。

問題点

①:IdCounterクラス内でdata変数をData型で定義しているがint型ではダメなのか
②:演算子のオーバーロードでは具体的にどのような定義を行っているのか

該当のソースコード

#include<iostream> using namespace std; class Data{ int num; public: Data() :num(0){} Data(int n) :num(n){} int getNum() const { return num;} }; class IdCounter{ static int nextID; Data data; public: int id; IdCounter() :data(Data(0)), id(++nextID){} IdCounter(Data d) :data(d), id(++nextID){} Data getData() const {return data;} IdCounter(const IdCounter& orig) :data(orig.data), id(++nextID){} IdCounter& operator=(const IdCounter& orig){ id = ++nextID; data = orig.data; return(*this); } }; int IdCounter::nextID = 100; int main(){ IdCounter a(Data(123)); cout << '[' << a.id << ']' << a.getData().getNum() << endl; IdCounter b(Data(456)); cout << '[' << b.id << ']' << b.getData().getNum() << endl; IdCounter c(Data(789)); cout << '[' << c.id << ']' << c.getData().getNum() << endl; IdCounter x1 = a, x2; x2 = a; cout << '[' << x1.id << ']' << x1.getData().getNum() << endl; cout << '[' << x2.id << ']' << x2.getData().getNum() << endl; return 0;

出力

[101]123
[102]456
[103]789
[104]123
[106]123

補足情報(FW/ツールのバージョンなど)

c++version : c++98

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

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

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

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

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

maisumakun

2022/11/30 03:02

> ②:演算子のオーバーロードでは具体的にどのような定義を行っているのか どの部分が演算子オーバーロードなのかは把握していますか?
yukziaru2587

2022/11/30 03:11

IdCounter(const IdCounter& orig) :data(orig.data), id(++nextID){} IdCounter& operator=(const IdCounter& orig){ id = ++nextID; data = orig.data; return(*this); } でしょうか?
episteme

2022/11/30 03:41

↑わかってるなら「具体的にどのような定義を行っているのか」は自明なのでは?
yukziaru2587

2022/11/30 03:48

定義と書きましたが、このオーバーロード後の挙動を理解できないというニュアンスです。分かりにくい書き方でした。
episteme

2022/11/30 03:52

代入(operator=)されるたびにnextID(通し番号)を更新してidを書き換えています。
yukziaru2587

2022/11/30 04:07

回答ありがとうございます。 data = orig.data; の部分では何を行っているか分かりますでしょうか?
episteme

2022/11/30 04:23

this->data に orig.data をコピーしています。
yukziaru2587

2022/11/30 04:32

回答ありがとうございます。ぐだぐだな質問に回答してくださり大変助かりました。
guest

回答1

0

ベストアンサー

int で書いても全く同じように動作するプログラムは作れます。 クラスを定義した意図を想像するならクラスを説明すること自体だと思われるので、この時点ではどうしてそうしたのかを考える意味はあまりありません。

ただ、プログラムというのは動作させたいことを書くというだけでなく問題を分解して小さな部品の組み合わせとして構成するのが綺麗なプログラムです。 規模がちょっと大きくなると整理されていないプログラムはわけがわからなくなります。 機能として int で十分だとしても整理の仕方のひとつとしてクラスで覆うというのはよくあることです。

過剰に覆うのもよくないので程度の見極めは微妙な匙加減があります。

x2 = a; と書いてあるところを x2.operator=(a); と書き換えても同じ動作です。 演算子オーバーロードもその実態は関数呼び出しにすぎず、呼び出しを短く書けるだけです。

短くかけるだけですが一般的にはその演算子から想像される動作を当てはめるのが望ましいと考えられており、 = を使えば当然に代入の動作になるべきです。 特に = は暗黙に呼び出されることもあるので変なことをすると全体の構成が無茶苦茶になりかねません。

質問中の例でも代入の動作はしていますね。 代入の動作のついでにカウンタの更新もしてくれるような定義になっています。

投稿2022/11/30 04:16

SaitoAtsushi

総合スコア5466

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

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

yukziaru2587

2022/11/30 04:31

ありがとうございます。解決しました!
yukziaru2587

2022/11/30 04:42

申し訳ありません IdCounter x1 = a, x2; の部分の挙動もご教授いただけないでしょうか?
episteme

2022/11/30 04:57

IdCounter x1 = a; IdCounter x2; と同じ。
yukziaru2587

2022/11/30 05:11

そういう省略法もあるんですね、、、。 大変勉強になります、またよろしくお願いいたします。
SaitoAtsushi

2022/12/01 23:49

変数の宣言は一か所に詰め込むよりは分けたほうが良い作法だと考えられています。 https://www.jpcert.or.jp/sc-rules/c-dcl04-c.html ちょっと複雑な時に勘違いしがちという理由なので単純なときはあまり気にされません (常に分けて書くべきというほどではありません) が、どのあたりから分かり難いと感じるかは人によるので他の人が読む可能性がある (チームで開発するときなど) は積極的に分けたほうが良いかもしれません。 程度問題なので匙加減は微妙なんですが……。
guest

あなたの回答

tips

太字

斜体

打ち消し線

見出し

引用テキストの挿入

コードの挿入

リンクの挿入

リストの挿入

番号リストの挿入

表の挿入

水平線の挿入

プレビュー

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

ただいまの回答率
85.47%

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

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

質問する

関連した質問