クラスのメンバ関数でない普通の自作関数をフレンド関数に設定すると自作関数の実行時そのクラス型のオブジェクトのメンバ変数にアクセスすることができるようになります

つづきです


ソーラー「🌞はぁ~🌞 いい運動になったなぁ~」


マックス「いつのまに 運動してたんだ?」


ソーラー「ちょっと部活に行ってました」


マックス「なにぃ」


ソーラー「フレンド関数のことも、もうわかっちゃったかな😊」


マックス「おお 部活とはフレンド関数の解読のことだったのか?」


ソーラー「合唱部ですよ 」


マックス「それ・・・運動・・・なのか?」


ソーラー「もう 気分爽快で


フレンド関数のことは任せてよ」


マックス「おお 頼もしいではないか🌞


ようは


自作関数operator+をフレンド関数に設定したなら


以下のようなビルドエラーが表示されるプログラムも実行できるようになるんだな

👇


#include <iostream>


using namespace std;


class Point{


private:

int x;

int y;


public:


void pointdisplay();


public:


void pointdisplay2(int i, int j);




};


void Point::pointdisplay() {


cout << x << "\n";

cout << y << "\n";

}


void Point::pointdisplay2(int i, int j) {


x = i;

y = j;


cout << x << "\n";

cout << y << "\n";

}


Point operator+(Point p, Point q) {


Point a;


a.x = p.x + q.x;

a.y = p.y + q.y;


return a;

}



int main() {


Point p1;

p1.pointdisplay2(1, 1);


Point p2;

p2.pointdisplay2(2, 2);



Point p3;

p3 = p1 + p2;

p3.pointdisplay();



return 0;

}


ビルド実行結果


重大度レベル コード 説明 プロジェクト ファイル 行 抑制状態

エラー (アクティブ) E0265 メンバー "Point::y" (宣言された 行 9) にアクセスできません

エラー (アクティブ) E0265 メンバー "Point::y" (宣言された 行 9) にアクセスできません

エラー (アクティブ) E0265 メンバー "Point::y" (宣言された 行 9) にアクセスできません

エラー (アクティブ) E0265 メンバー "Point::x" (宣言された 行 8) にアクセスできません

エラー (アクティブ) E0265 メンバー "Point::x" (宣言された 行 8) にアクセスできません

エラー (アクティブ) E0265 メンバー "Point::x" (宣言された 行 8) にアクセスできません

エラー C2248 'Point::y': private メンバー (クラス 'Point' で宣言されている) にアクセスできません。

エラー C2248 'Point::x': private メンバー (クラス 'Point' で宣言されている) にアクセスできません。


ソーラー「ここはまかせてよ😊


そう


クラスPointのメンバ変数宣言


int x;

int y;


のアクセス指定子が


privateに設定されているとします


その状態で


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

Point p1;

Point p2;


実行して


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

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


を作製して


p1+p2;


つまり


operator+(p1,p2);


つまり


自作関数operator+の定義


Point operator+(Point p, Point q) {


Point a;


a.x = p.x + q.x;

a.y = p.y + q.y;


return a;

}


Point pにp1

Point qにp2


が代入された


Point a;


a.x = p1.x + p2.x;

a.y = p1.y + p2.y;


return a;


を実行しようとしても


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


p1.x

p1.y


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


p2.x

p2.y



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


a.x

a.y



を使用することはできないので


a.x = p1.x + p2.x;

a.y = p1.y + p2.y;



実行することはできません。



☆  ☆  ☆


ちょっと解説


このプログラムでは


(クラスPointのメンバ変数宣言


int x;

int y;


のアクセス指定子が


privateに設定されています


この場合


main関数内で


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

Point p1;

Point p2;


実行して


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

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


を作製しても


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

p1.x

p1.y


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

p2.x

p2.y

直接用いて


p1.x=1;

p1.y=1;


p2.x =2;

p2.y =2;

のように数値データを代入することはできません


同様に


クラスPointのメンバ関数でない普通の自作関数operator+


の実行においても


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

p1.x

p1.y


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

p2.x

p2.y


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

a.x

a.y


を使用することはできません


ですので


p1+p2;


つまり


operator+(p1,p2);


の実行の前に



Point p1;

p1.pointdisplay2(1, 1);


Point p2;

p2.pointdisplay2(2, 2);


を実行して


セッター関数であるクラスPointのメンバ関数pointdisplay2を通して



           😊間接的に😊



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

p1.x

p1.y


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

p2.x

p2.y


数値データ

1

1


2

2


を代入しています



それでもビルドエラーが表示されています

                       solarplexussより)


☆  ☆  ☆


そこで


p1+p2;


つまり


operator+(p1,p2);


つまり


自作関数operator+の定義


Point operator+(Point p, Point q) {


Point a;


a.x = p.x + q.x;

a.y = p.y + q.y;


return a;

}


Point pにp1

Point qにp2


が代入された


Point a;


a.x = p1.x + p2.x;

a.y = p1.y + p2.y;


return a;


が実行できるよう


普通の自作関数operator+を


フレンド関数に設定して


普通の自作関数operator+が


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

p1.x

p1.y


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

p2.x

p2.y


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

a.x

a.y


にアクセスすることができるようにしてみたいと思います。



普通の自作関数operator+関数をフレンド関数に設定するには


クラスPointのクラス宣言

👇

class Point{


private:

int x;

int y;


public:


void pointdisplay();


public:


void pointdisplay2(int i, int j);


};



内に


普通の自作関数operator+関数のフレンド関数宣言


friend Point operator+(Point p, Point q);


を付け加えます。


friendが普通の自作関数operator+関数


Point operator+(Point p, Point q)



先頭に付けられていますね。


すると


クラスPointのクラス宣言は

👇

class Point{


private:

int x;

int y;


public:


void pointdisplay();


public:


void pointdisplay2(int i, int j);


public;


friend Point operator+(Point p, Point q);


};


となります。



このように


operator+関数をフレンド関数に設定すると


operator+関数は


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

p1.x

p1.y


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

p2.x

p2.y


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

a.x

a.y


にアクセスすることができるようになるので


p1+p2;


つまり


operator+(p1,p2);


つまり


自作関数operator+の定義


Point operator+(Point p, Point q) {


Point a;


a.x = p.x + q.x;

a.y = p.y + q.y;


return a;

}


Point pにp1

Point qにp2


が代入された


Point a;


a.x = p1.x + p2.x;

a.y = p1.y + p2.y;


return a;


が実行できるようになります。


それでは


実際に


operator+関数をフレンド関数に設定して


p1+p2;


を実行してみたいと思います


そのプログラムはこちらになります」

👇


#include <iostream>


using namespace std;


class Point {


private:

int x;

int y;


public:


void pointdisplay();


public:


void pointdisplay2(int i, int j);


public:


friend Point operator+(Point p, Point q);



};


void Point::pointdisplay() {


cout << x << "\n";

cout << y << "\n";

}


void Point::pointdisplay2(int i, int j) {


x = i;

y = j;


cout << x << "\n";

cout << y << "\n";

}


Point operator+(Point p, Point q) {


Point a;


a.x = p.x + q.x;

a.y = p.y + q.y;


return a;

}



int main() {


Point p1;

p1.pointdisplay2(1, 1);


Point p2;

p2.pointdisplay2(2, 2);



Point p3;

p3 = p1 + p2;

p3.pointdisplay();



return 0;

}



プログラムの実行結果


1

1

2

2

3

3



マックス「おぉ


p1+p2;



実行できたじゃないか



Point p1;

p1.pointdisplay2(1, 1);


Point p2;

p2.pointdisplay2(2, 2);


の実行により


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

p1.x

p1.y


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

p2.x

p2.y


数値データ


1

1


2

2


が代入される


そのあと


p3 = p1+p2;


の実行により


普通の自作関数operator+の定義内の

👇

Point operator+(Point p, Point q) {


Point a;


a.x = p.x + q.x;

a.y = p.y + q.y;


return a;

}

👆


pにp1

qにp2


が代入された


Point a;


a.x=p1.x+p2.x;

a.y=p1.y+p2.y;


return a;


が実行され


p1+p2には


戻り値として


p1.x+p2.x

p1.y+p2.y

の格納している数値データ


3

3


が返されることになる


なので


p3 = p1+p2;


の実行により


数値データ


3

3

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


p3.x

p3.y



代入されることになるんだろう


あとは

p3.pointdisplay();


の実行により


3

3



コマンドプロンプト画面に表示されるというわけだ😊



なんだ 


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


operator+関数のフレンド関数宣言


friend Point operator+(Point p, Point q);


を記述するだけで


operator+関数は


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

p1.x

p1.y


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

p2.x

p2.y


アクセスすることができるようになるのか( ̄▽ ̄)/」


ソーラー「そうなんです


このように


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


普通の自作関数operator+関数のフレンド関数宣言


を実行することにより


普通の自作関数operator+関数は


クラスPointのメンバ変数宣言


int x;

int y;


のアクセス指定子が



            💖private💖



に設定されていても


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

p1.x

p1.y


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

p2.x

p2.y


にアクセスすることができるようになります


まあ


もともと


クラスPointのメンバ変数宣言


int x;

int y;


のアクセス指定子が



            🍋public🍋



なら


operator+関数を


フレンド関数に設定しなくても


operator+関数は


ふつうに


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

p1.x

p1.y


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

p2.x

p2.y


アクセスすることができ


p1+p2;

すなわち

operator+(p1,p2);


実行できるんだけどね😊


そして


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


operator+関数のフレンド関数宣言


friend Point operator+(Point p, Point q);


が記述されているといっても


これは


普通の自作関数operator+関数のフレンド関数宣言


であり


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


ではありません。


ですから


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


Point p1;


を実行したとしても


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


p1.operator+(Point p, Point q)


のようなものは


生成されないんだね。


もちろん


p1.operator+(p1, p2);を実行することもできません


そのことを示すプログラムはこちらです

👇


#include <iostream>


using namespace std;


class Point {


private:

int x;

int y;


public:


void pointdisplay();


public:


void pointdisplay2(int i, int j);


public:


friend Point operator+(Point p, Point q);



};


void Point::pointdisplay() {


cout << x << "\n";

cout << y << "\n";

}


void Point::pointdisplay2(int i, int j) {


x = i;

y = j;


cout << x << "\n";

cout << y << "\n";

}


Point operator+(Point p, Point q) {


Point a;


a.x = p.x + q.x;

a.y = p.y + q.y;


return a;

}



int main() {


Point p1;

p1.pointdisplay2(1, 1);


Point p2;

p2.pointdisplay2(2, 2);



Point p3;

p3 =p1.operator+(p1, p2);//🌞ここに注目🌞p3=p1+p2;の代わりにp3 =p1.operator+(p1, p2);を記述しました

p3.pointdisplay();



return 0;

}


ビルド実行結果



エラー (アクティブ) E0135 class "Point" にメンバー "operator+" がありません

エラー C2039 '+': 'Point' のメンバーではありません。

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

作者を応援しよう!

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

応援したユーザー

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

新規登録で充実の読書を

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

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

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