メンバ関数の定義で戻り値が返されるように設定されているとオブジェクトのメンバ関数が実行されるとオブジェクトのメンバ関数に戻り値が返されます

🌞   🌞   🌞   🌞   🌞   🌞   🌞


クラスPointのメンバ関数operator+関数の定義

👇


Point Point::operator+(Point p)

{

Point a;


a.x = x + p.x;

a.y = y + p.y;


return a;

}




なぜ


Point Point::operator+(Point p)



記述されているのか


わかったかな?


     簡単だった?


🌞   🌞   🌞   🌞   🌞   🌞   🌞


ソーラー「最初 見た時は


まったく


意味不明だったけど・・・」


マックス「それほどでもなかったな( ̄ー ̄)ニヤリ」



マックス「ところで 



           皆の衆


                         」



ソーラー「はい」


マックス「


ところで


Point Point::operator+(Point p)



1番左端のPointはなんなんだ?」


ソーラー「えっ?」


マックス「つまり


1番左端のPointは戻り値の型ということだったが


意味がわからん?


Pointはクラス名じゃないか」


ソーラー「それは簡単です。


クラスPointのメンバ関数operator+関数の定義

👇


Point Point::operator+(Point p)

{

Point a;


a.x = x + p.x;

a.y = y + p.y;


return a;

}

👆

で用いられている


Point Point::operator+(Point p)



クラスPointのクラス宣言内の


operator+関数のクラスPointのメンバ関数宣言


Point operator+(Point p);



Point operator+(Point p)



このoperator+関数の定義が


クラスPointのメンバ関数operator+の定義になるように


Point::



Point



operator+(Point p)


の間に


くっつけられたものです。


このPoint::がくっつけられていなければ


この定義は


クラスPointのメンバ関数operator+関数の定義とはならないんです


つまり

以下のように

👇  👇ここです

Point Point::operator+(Point p)

{

Point a;


a.x = x + p.x;

a.y = y + p.y;


return a;

}

👆



Point::がくっついていれば


Point Point::operator+(Point p)

{

Point a;


a.x = x + p.x;

a.y = y + p.y;


return a;

}



クラスPointのメンバ関数operator+関数の定義となるのですが


以下のように

👇  

Point operator+(Point p)

{

Point a;


a.x = x + p.x;

a.y = y + p.y;


return a;

}

👆



Point::がくっついていなければ


Point operator+(Point p)

{

Point a;


a.x = x + p.x;

a.y = y + p.y;


return a;

}


クラスPointのメンバ関数operator+関数の定義とはならないんです


(ここの部分は文末で詳しく解説されています)






operator+関数のクラスPointのメンバ関数宣言


Point operator+(Point p);



一番左端のPointは


クラスPoint型のオブジェクトが生成され


クラスPoint型のオブジェクトのメンバ関数である


operator+関数が


実行されたときに


クラスPoint型のオブジェクトのメンバ関数である


operator+関数に


戻される戻り値を格納する型


であり


Point operator+(Point p)の()内のPoint pは


クラスPoint型のオブジェクトのメンバ関数であるoperator+関数が実行されるとき


引数として代入されるオブジェクトを格納するために


設定されています。


たとえば


クラスPoint型のオブジェクトp2が引数としてPoint pに代入された


クラスPoint型のオブジェクトp1のメンバ関数である


p1.operator+(p2);



実行されるときに


p1.operator+(p2)


に戻される戻り値を格納する型



クラスの型Pointになるというわけです」



マックス「なんで


p1.operator+(p2);



実行されたときに


         🌞p1.operator+(p2)🌞


に戻り値が戻されることになるんだ?」


ソーラー「それは


         関数の実行時に


       関数に戻り値が返される


という基本的なルールがありますが


同様に


      オブジェクトのメンバ関数の実行時に


 オブジェクトのメンバ関数に戻り値が返される


という基本的なルールがあるからなんです


例えば


次のような


クラスCubeを見てください


class Cube {


public:

int no; //変数noはクラスCubeのメンバ変数とよばれます


public:

int display(int a); /*自作関数display(int a)はクラスCubeのメンバ関数とよばれます

🌞👆戻り値を格納する型がintになっています🌞*/


};


int Cube::display(int a){


no = a;


cout << "立方体につけられたナンバーは" << no << "です" << "\n";



return a ;

}


ソーラー「このクラスCubeのクラス宣言内では


クラスCubeのメンバ関数宣言


int display(int a);


が設定されています。


この左端のintは


Cube型のオブジェクトが生成され


Cube型のオブジェクトのメンバ関数display(int a)が


実行されたとき


Cube型のオブジェクトのメンバ関数display(int a)に


返される


戻り値を格納するために設定されています。


では


このクラスCubeが用いられたプログラムをご覧ください

👇


#include <iostream>


using namespace std;


class Cube{


public:

int no; //変数noはクラスCubeのメンバ変数とよばれます


public:

int display(int a); //自作関数display(int a)はクラスCubeのメンバ関数とよばれます


};


int Cube::display(int a) {


no = a;


cout << "立方体につけられたナンバーは" << no << "です" << "\n";



return a;

}


//👆クラスCubeのメンバ関数となっているdisplay(int a) の定義をおこなっています


/*🌞🌞🌞ここでの注目ポイントは


no = a;


が実行されていることです


この命令文が実行されると


クラスCube型のオブジェクトcube1のメンバ変数


cube1.no


格納されている数値データは

変数

a


に格納されている数値データに変更されることになります。


cube1.display(5);


が実行されると


aに5が代入され


return a;


が実行されるので


cube1.display(5);


に戻り値として5が返されます



🌞🌞🌞*/



int main() {


Cube cube1;


//👆cube1のクラスCube型のオブジェクト宣言をおこなっています


cube1.no = 1;


cout << "立方体につけられたナンバーは" << cube1.no << "です" << "\n";



  cout << "cube1.display(5)に戻される戻り値は" << cube1.display(5) << "です" << "\n";

 

return 0;

}



プログラムの実行結果


立方体につけられたナンバーは1です

立方体につけられたナンバーは5です

cube1.display(5)に戻される戻り値は5です


ソーラー「このプログラムでは


引数に数値データが代入された


クラスCube型のオブジェクトcube1のメンバ関数


cube1.display(5);


が実行されています。


そして

cube1.display(5);


が実行されると


cube1.display(5)


には戻り値として


5


が返されることになります


この5は


戻り値を格納する型


int型の形式で格納されることになります



つまり


       引数に数値データが代入された


  クラスCube型のオブジェクトcube1のメンバ関数


        cube1.display(5);



が実行されたとき


   

       引数に数値データが代入された


  クラスCube型のオブジェクトcube1のメンバ関数


        cube1.display(5)


          そのものに


戻り値5が返されることになります


同様に


       引数にオブジェクトp2が代入された


    クラスPoint型のオブジェクトp1のメンバ関数である


           p1.operator+(p2);



実行されたときに



クラスPoint型のオブジェクトp1のメンバ関数


          🌞p1.operator+(p2)🌞


に戻り値が返されることになります。


このときの戻り値を格納する型が


クラスの型Pointというわけです。」



マックス「なんだ そんな 基本的なルールがあったのか・・・って


確かに


普通の自作関数もそうだな」


int(イント)「むしろ


 cout << "cube1.display(5)に戻される戻り値は" << cube1.display(5) << "です" << "\n";

 

が実行されると


cube1.display(5);


が実行されたあと


 cout << "cube1.display(5)に戻される戻り値は" << cube1.display(5) << "です" << "\n";

 


cube1.display(5)



5が代入された


cout << "cube1.display(5)に戻される戻り値は" << 5 << "です" << "\n";


が実行されるのが


意外な発見だったね。


cube1.display(5)に戻り値ってちゃんと返っているんだね


よかったね」



マックス「ぬあぬぃ それには気付かなかった」


ソーラー「以前のエピソードでも見てきたように


cout << 自作関数<< "\n";


が実行されると


自作関数が実行されたのち


自作関数の戻り値が代入された


cout << 自作関数の戻り値<< "\n";


が実行されるのでしたね」


マックス「思わぬ発見だな


ところで


一番左端のPointは


引数にオブジェクトp2が代入された


クラスPoint型のオブジェクトp1のメンバ関数operator+


つまり


p1.operator+(p2);



実行されたときに


🌞p1.operator+(p2)🌞に


返される戻り値を格納する型


なのは分かった・・・


ということは・・・だ・・・


  一番左端のPointは


  🌞クラスの型Point🌞なので


引数にオブジェクトp2が代入された


クラスPoint型のオブジェクトp1のメンバ関数


p1.operator+(p2);



実行されたときに


クラスPoint型のオブジェクトのメンバ関数


p1.operator+(p2)に戻される戻り値は



     🌞クラスPoint型のオブジェクト🌞



ということになるんじゃないか…?


まさか


  🌞クラスの型Point🌞に


整数値1だけが格納されるってことはないだろう



ということは




p1.operator+(p2)に戻される戻り値は



     🌞クラスPoint型のオブジェクト🌞



ということになるんじゃないか…?



ソーラー「あっ 本当ですね。


intの関数が実行されたとき


整数値が戻り値として関数に返されるのなら


同様に


Pointの関数の戻り値にはクラスPoint型のオブジェクトが返されるというわけだね


オブジェクトが戻り値として返されるというのは


今までにないパターンだね」




ソーラー「う~ん


つまり


オブジェクト同士の足し算である


p1+p2;


が実行されるとき


ええと・・・


p1+p2;


が実行されるということは


p1.operator+(p2);


が実行されるということなんですが


p1.operator+(p2);


が実行されたとき


p1.operator+(p2)に返される戻り値が


クラスPoint型のオブジェクトになる


ということなんですよね


となると



p1.operator+(p2);


が実行されると


p1.operator+(p2)



クラスPoint型のオブジェクト


が戻り値として返されるのなら



p1.operator+(p2);


が実行されることは


p1+p2;


が実行されることに等しいので



クラスPoint型のオブジェクト同士の足し算である


p1+p2


に戻される戻り値は



クラスPoint型のオブジェクト


ということになる・・・



           でも


          なんだろう 



p1.operator+(p2)


すなわち


p1+p2に


クラスPoint型のオブジェクト


が戻されると


なにかいいことがあるのかな?


そもそも


          p1+p2;



すなわち


        p1.operator+(p2);



        が実行されると


         戻り値が


        p1.operator+(p2) 



に返されたとしても


それは


        p1.operator+(p2);


        の実行結果


の話であって


        p1.operator+(p2);


の実行内容


 がなんなのか?


       p1.operator+(p2);


が実行されると何がおこるのか?


       については


       p1.operator+(p2);


を見ただけでは


      全く分からないね」


マックス「そこで


クラスPointのメンバ関数operator+関数の定義

👇


Point Point::operator+(Point p)

{

Point a;


a.x = x + p.x;

a.y = y + p.y;


return a;

}


が登場してくるってわけだな(#^^#)」




ソーラー「ふぅむ



           やはり


    ここ『演算子のオーバーロード』の世界は


        


          ファンタジーの世界



            みたいだね


     次々と  面白い考察が得られるね



          なんだか 奥ゆかしいね




      『演算子のオーバーロード』の世界 



          まるで



         異世界のようだね


ははっ


だったら



    僕らは異世界に転生してたってことになるかな😊」

              

int(イント)


「だったら この小説のカテゴリーは異世界転生系になるんじゃない?」


マックス「いつのまに


カテゴリーが異世界転生系に・・・」


ソーラー「まあ、もともと この小説のカテゴリーは


フランス語講座とお料理に分類されていました


ですから


どのカテゴリーに分類されても


そんなに問題ないかな(*´▽`*)」


てんC「そ、そうだったんですか・・・」






🌞   🌞   🌞   🌞   🌞   🌞   🌞


         すごい 


         さすが


    😊どのカテゴリーに分類されても😊


       😊そんなに問題ない😊



       そのことに気づくなんて・・・・・



         そう


          p1+p2;



すなわち


        p1.operator+(p2);

 


        が実行されると


        p1.operator+(p2)




戻り値が返されることはわかりましたが


それは


      関数が実行されるときの


       基本的な性質であって




          p1+p2;



すなわち


        p1.operator+(p2);

 


        が実行されると



      何が実行されるかまでは



          現時点では


           まだ  


         わかりません。


         

クラスPointのメンバ関数operator+関数の定義

👇


Point Point::operator+(Point p)

{

Point a;


a.x = x + p.x;

a.y = y + p.y;


return a;

}



の内容にふれて



         初めて


         そう


          p1+p2;



すなわち


        p1.operator+(p2);

 


        が実行されると



       何が実行されるかが



       理解できるようになります。


        

     そこを見抜くなんて驚いちゃった



  そう

   

          🌞p1+p2;🌞


        🌞p1.operator+(p2);🌞


が実行されると何が起こるかを


決めるのが


クラスPointのメンバ関数operator+関数の定義

👇


Point Point::operator+(Point p)

{

Point a;


a.x = x + p.x;

a.y = y + p.y;


return a;

}



なんです。


🌞   🌞   🌞   🌞   🌞   🌞   🌞



マックス「うむぅ そういうことだったのか」



🌞   🌞   🌞   🌞   🌞   🌞   🌞


         後はいよいよ


クラスPointのメンバ関数operator+関数の定義

👇


Point Point::operator+(Point p)

{

Point a;


a.x = x + p.x;

a.y = y + p.y;


return a;

}


の定義内容


Point a;


a.x = x + p.x;

a.y = y + p.y;


return a;



考察だけとなったけど


          準備はいいかな?


🌞   🌞   🌞   🌞   🌞   🌞   🌞


マックス「いつでもこ~い


皆も準備は整ったか」


ソーラー「もちろん ばっちりだね(^_-)-☆」


てんC「はい マックスさん」




マックス「では


つづきといくか😊」










おまけのコーナーの時間です



以下のように

👇  👇ここです

Point Point::operator+(Point p)

{

Point a;


a.x = x + p.x;

a.y = y + p.y;


return a;

}

👆



Point::がくっついていれば


Point Point::operator+(Point p)

{

Point a;


a.x = x + p.x;

a.y = y + p.y;


return a;

}



クラスPointのメンバ関数operator+関数の定義となるのですが


以下のように

👇  

Point operator+(Point p)

{

Point a;


a.x = x + p.x;

a.y = y + p.y;


return a;

}

👆



Point::がくっついていなければ


Point operator+(Point p)

{

Point a;


a.x = x + p.x;

a.y = y + p.y;


return a;

}


クラスPointのメンバ関数operator+関数の定義とはならないんです




🐤  🐤  🐤  🐤  🐤ぴよぴよ


この場合


Point operator+(Point p)

{

Point a;


a.x = x + p.x;

a.y = y + p.y;


return a;

}


普通の自作関数の定義とみなされますが


クラスPointのメンバ関数operator+関数の定義でない


普通の自作関数の定義なのに


クラスPointのメンバ変数x

クラスPointのメンバ変数y


がもちいられているので


プログラム内で


Point operator+(Point p)

{

Point a;


a.x = x + p.x;

a.y = y + p.y;


return a;

}

が用いられていると


xが定義されていません

yが定義されていません



ビルドエラーが表示されることになります


ですので


Point operator+(Point p)

{

return p;

} 

のように


クラスPointのメンバ変数x

クラスPointのメンバ変数y


がもちいられていなければ


ビルドエラーが表示されることはなく


自作関数operator+関数の定義が行われたことになります


そして


Point p1;


operator+(p1);


が実行されると


クラスPoint型のオブジェクトp1が


operator+関数の定義

👇


Point operator+(Point p)

{

return p;

} 



Point p


に代入されたものが実行され


operator+(p1)には


戻り値としてp1が返されることになります


ここに関しては


次に続くエピソードでさらに詳しく解説されていきます


🐤  🐤  🐤  🐤  🐤ぴよぴよ


  • Twitterで共有
  • Facebookで共有
  • はてなブックマークでブックマーク

作者を応援しよう!

ハートをクリックで、簡単に応援の気持ちを伝えられます。(ログインが必要です)

応援したユーザー

応援すると応援コメントも書けます

新規登録で充実の読書を

マイページ
読書の状況から作品を自動で分類して簡単に管理できる
小説の未読話数がひと目でわかり前回の続きから読める
フォローしたユーザーの活動を追える
通知
小説の更新や作者の新作の情報を受け取れる
閲覧履歴
以前読んだ小説が一覧で見つけやすい
新規ユーザー登録無料

アカウントをお持ちの方はログイン

カクヨムで可能な読書体験をくわしく知る