C++のフレンド関数

2013/5/14の「応用プログラミングA(C++)」の講義ふりかえり.

Q1は,独習C++の3章までの復習として関数とオブジェクト.
クラスに属していないメイン関数を作って,先に現れているクラスCoordを引数や戻り値に指定している.

[code lang=”cpp”]
#include
#include
using namespace std;
//クラスCoordの宣言
class Coord {
double x,y,z;
public:
void set_x(double u) {x=u;}
void set_y(double v) {y=v;}
void set_z(double w) {z=w;}
double get_x() {return x;}
double get_y() {return y;}
double get_z() {return z;}
void Show();
};
void Coord::Show() {
cout << "(" << x << "," << y << "," << z << ")";
}

//Coordオブジェクトを返す、中点を求める関数
Coord mid_Coord(Coord ob1, Coord ob2);
//Coordオブジェクトを返す、距離を求める関数
double dist_Coord(Coord ob1, Coord ob2);

int main() {
Coord p1,p2,p3;
//p1,p2に3次元座標をセットしていく
p1.set_x(1.0f); p1.set_y(6.5f); p1.set_z(-10.0f);
p2.set_x(-1.0f); p2.set_y(1.5f); p2.set_z(4.0f);

cout << "点A"; p1.Show(); cout << endl;
cout << "点B"; p2.Show(); cout << endl;
//中点p3を取得
p3 = mid_Coord(p1,p2);
cout <<"ABの中点"; p3.Show(); cout << endl;
//距離を求める,値を返すだけなのでリダイレクトで出力できる
cout <<"AB間の距離" << dist_Coord(p1,p2) << endl;
return 0;
}
//中点を求める関数の実装
Coord mid_Coord(Coord ob1, Coord ob2) {
Coord ob;
ob.set_x( (ob1.get_x() + ob2.get_x()) / 2.0f );
ob.set_y( (ob1.get_y() + ob2.get_y()) / 2.0f );
ob.set_z( (ob1.get_z() + ob2.get_z()) / 2.0f );
return ob;
}
//距離を求める関数の実装,1行で実装してみる
double dist_Coord(Coord ob1, Coord ob2) {
return sqrt(
( ob2.get_x() – ob1.get_x() ) * ( ob2.get_x() – ob1.get_x() ) +
( ob2.get_y() – ob1.get_y() ) * ( ob2.get_y() – ob1.get_y() ) +
( ob2.get_z() – ob1.get_z() ) * ( ob2.get_z() – ob1.get_z() )
);
}
[/code]

Q2はQ1の復習に引き続き,「フレンド関数」を使った実装方法を学ぶ.
色名と色の値を扱うクラスCNameを引数として,円クラスCircleのオブジェクトに対して,「色が一致しているか?」を判定するisSame(CName col)を宣言・実装する必要が有るため friend を名乗る必要がある.

[code lang=”cpp”]
#include <iostream>
#include <cstring>
using namespace std;
class CName;//ここはクラス名だけ宣言してみた
class Circle {
double x,y,radius; int r,g,b;
public:
void set_xyr(double s, double t, double r) { x = s; y = t; radius = r; }
void set_color(int u, int v, int w) { r = u; g = v; b = w; }
void Show();
bool isSame(CName col);
};
class CName {
char name[50]; int r,g,b;
public:
CName (char* str, int u, int v, int w);
char* get_name() { return name; }
void Show();
friend bool Circle::isSame(CName col);
};
//friend関数isSameの実装
bool Circle::isSame(CName col) {
if (r == col.r && g == col.g && b == col.b ) {
return true;
} else {
return false;
}
}
//CName(色名,RGB値)のコンストラクタ
CName::CName(char* str, int u, int v, int w) {
strcpy(name, str);
r = u; g = v; b = w;
}
void CName::Show() {
cout << name << ":(" << r << "," << g << "," << b << ")\n";
}

int main() {
Circle c;
CName co1("Red",255,0,0); CName co2("Green",0,255,0); CName co3("Blue",0,0,255);
c.set_xyr(2.0f,3.0f,5.0f);
c.set_color(255,0,0); //赤
cout << "円の情報を表示\n"; c.Show();
cout << "色1の情報を表示\n"; co1.Show();
cout << "色2の情報を表示\n"; co2.Show();
cout << "色3の情報を表示\n"; co3.Show();
cout << "この円の色は" << co1.get_name();
if (c.isSame(co1)) {
cout << "です" << endl;
} else {
cout << "ではありません" << endl;
}
cout << "この円の色は" << co2.get_name();
if (c.isSame(co2)) {
cout << "です" << endl;
} else {
cout << "ではありません" << endl;
}
cout << "この円の色は" << co3.get_name();
if (c.isSame(co3)) {
cout << "です" << endl;
} else {
cout << "ではありません" << endl;
}

return 0;
}
//void Show()の実装
void Circle::Show() {
cout << "座標("<< x << ","<< y <<") 半径=" << radius << endl;
cout << "RGB=("<< r <<","<< g <<","<< b << ")" << endl;
}
[/code]

Q3はQ2の配列による拡張.

まだ課題提出締め切り前なので,main文以下だけ掲示しておきます.→全文掲載しました

[code lang=”cpp”]
#include
#include
using namespace std;

class CName;

class Circle {
double x, y;
double radius;
int r, g, b;
public:
void set_xyr(double s, double t, double r) {
x = s;
y = t;
radius = r;
}
void set_color(int u, int v, int w) {
r = u;
g = v;
b = w;
}
void show();
bool isSame(CName col);
};

class CName {
char name[50];
int r, g, b;
public:
CName(char* str, int u, int v, int w);
char* get_name() {
return name;
}
void show();
friend bool Circle::isSame(CName col);
};

void Circle::show() {
cout << "座標:(" << x << "," << y << ")\n";
cout << "半径:" << radius << "\n";
cout << "RGB:(" << r << "," << g << "," << b << ")\n";
}

bool Circle::isSame(CName col) {
if (r == col.r && g == col.g && b == col.b)
return true;
else
return false;
}

CName::CName(char* str, int u, int v, int w) {
strcpy(name, str);
r = u;
g = v;
b = w;
}

void CName::show() {
cout << name << ":(" << r << "," << g << "," << b << ")\n";
}

int main() {
Circle ob[3];
CName co[8] = { CName("White", 255, 255, 255),
CName("Black", 0, 0, 0),
CName("Red", 255, 0, 0),
CName("Green", 0, 255, 0),
CName("Blue", 0, 0, 255),
CName("Cyan", 0, 255, 255),
CName("Magenta", 255, 0, 255),
CName("Yellow", 255, 255, 0) };
int i, j, flag;

ob[0].set_xyr(2.0, 3.0, 5.0);
ob[0].set_color(255, 0, 0);
ob[1].set_xyr(4.0, 5.0, 6.5);
ob[1].set_color(0, 255, 0);
ob[2].set_xyr(1.5, 1.5, 2.0);
ob[2].set_color(150, 150, 150);

for (i = 0; i < 3; i++) {
cout << "円" << i+1 << "の情報を表示\n";
ob[i].show();
}

cout << "\n登録してある色一覧\n";
for (i = 0; i < 8; i++) {
co[i].show();
}
cout << "\n";

for (i = 0; i < 3; i++){
flag = 0;
for (j = 0; j < 5; j++) {
if (ob[i].isSame(co[j])) {
cout << "円" << i+1 << "の色は" << co[j].get_name() << "です\n";
flag = 1;
break;
}
}
if (!flag) {
cout << "円" << i+1 << "の色は登録されている色にありません\n";
}
}

return 0;
}
[/code]

【実行結果】

半径:5
GB:(255,0,0)
円2の情報を表示
座標:(4,5)
半径:6.5
GB:(0,255,0)
円3の情報を表示
座標:(1.5,1.5)
半径:2
GB:(150,150,150)

登録してある色一覧
hite:(255,255,255)
lack:(0,0,0)
ed:(255,0,0)
reen:(0,255,0)
lue:(0,0,255)
yan:(0,255,255)
agenta:(255,0,255)
ellow:(255,255,0)

円1の色はRedです
円2の色はGreenです
円3の色は登録されている色にありません

次回は「C++でのポインタと配列の利用」です。

C++のフレンド関数」への1件のフィードバック

コメントは受け付けていません。