include

オブジェクト指向言語
オブジェクト指向言語演習
第23回 C++言語 クラスの詳細
スケジュール(C++言語)
20.
21.
22.
23.
24.
オブジェクト指向技術
C++言語 コンソール入出力とクラス
C++言語 クラスの継承
C++言語 クラスの詳細
C++言語 オーバーロード
(2004/12/13)
(2004/12/20)
(2004/12/20)
(2005/01/17)
(2005/01/17)
-- 希望者に対するC++補講--
(予定日未定)
25. C++言語
26. C++言語
27. C++言語
クラスの継承
マニピュレータ, ファイル入出力
テンプレート
(2005/01/24)
(2005/01/24)
(2005/01/31)
期末試験 2005/02/01 (9:00-10:30 (他の時間が空けば移動))
(授業期間終了は1月31日ですが、2月1日は補講日です)
13.Dec.2004
Object Oriented Language - Y.Nagasaka: [email protected]
2
C++言語 クラスの詳細
C++ Language
Detail description for Class
前回までの復習(1)
 C++のコンソール入出力
 入力演算子
>>
 cin >>「 変数」;
出力演算子 <<
「変数、式」 << cout;
 クラスの概要
 クラスの宣言
 アクセス制限 private, public, protected
 クラスの定義
 クラスで宣言されたメンバ関数の内容を定義する
 オブジェクトの宣言
 クラスは「型」であるので、実際に使うときには「変数」
に相当するオブジェクトを宣言し、使用する
 コンストラクタとデストラクタ
 オブジェクトが生成・消滅されたときに実行される
13.Dec.2004
Object Oriented Language - Y.Nagasaka: [email protected]
4
前回までの復習(2)
 クラスの継承
 あるクラスが他のクラスの性質をそのまま受け継ぐ仕組み
B
 継承されるクラス スーパークラス(B)
 class B { }
 継承したクラス
サブクラス(D)
 class D: public B{ };
 インライン関数
D
 関数を展開する
 inline int func {}
 戻り値型intの関数func
 自動インライン関数
 クラス宣言内のメンバ宣言時に関数を定義する
 インライン関数の制限
 静的変数、繰り返し制御、switch文や再帰を用いた場合
13.Dec.2004
Object Oriented Language - Y.Nagasaka: [email protected]
5
オブジェクトの代入(1)
 2つのオブジェクトの型が同じ(オブジェクトを生成
した元のクラスが同じ)であれば、オブジェクトの代
入を行うことができる。
 代入は元のオブジェクトの内容を代入先のオブジェ
クトに全てコピーする
 例え配列のように大きな領域を使用するものをメンバとし
て持っていたとしても(文字列の代入ができる)
 ただし、同じ内容をもつオブジェクトでも元のクラ
スが異なる場合には代入は出来ない。
 この場合は内容を一つ一つコピーする必要がある
13.Dec.2004
Object Oriented Language - Y.Nagasaka: [email protected]
6
オブジェクトの代入(2)
●リスト3.1 (オブジェクト代入の例)
#include <iostream>
using namespace std;
//
class myclass {
//
int a, b;
//
public:
void set(int i, int j) { a
void show() { cout << a <<
};
int main()
{
myclass o1, o2;
std名前空間を省略して使用する
クラスmyclassの宣言
private属性の変数a,bを宣言
= i; b = j; }
' ' << b << "\n"; }
// メンバ関数set
// メンバ関数show
// どちらもinline関数
// オブジェクトo1とo2を宣言する
o1.set(10, 4);
// メンバ関数setでprivate属性のa,bの値を設定する
o2 = o1;
o1.show();
o2.show();
return 0;
// o1をo2に代入する
// メンバ関数showを使用
}
13.Dec.2004
Object Oriented Language - Y.Nagasaka: [email protected]
7
関数へのオブジェクトの引き渡し
 関数に引数として変数などのデータを渡すのと同じ
方法でオブジェクトを引数として渡すこともできる
 関数へはデフォルトとして「値呼び出し(pass by
value)」が使われる
 値呼び出しなので、引数で渡されるオブジェクトの
コピーが生成されて関数に渡される
 従って、関数内でオブジェクトを変更しても呼び出し元の
オブジェクトに変更は反映されない。
 関数が呼び出されたときにコピーされ、終了時には破棄さ
れる。コンストラクタ・デストラクタは呼び出されない。
 C言語と同様に、関数側での変更を受け取りたい場合
にはポインタを渡す。
13.Dec.2004
Object Oriented Language - Y.Nagasaka: [email protected]
8
関数からのオブジェクトの返し
 関数にオブジェクトを渡すことができるのと同様に、
関数からオブジェクトを返すことができる。
 関数からオブジェクトを戻すときにはreturn文を使
用する。
 変数を返す関数(これまでC言語で学習した)と同じ
ように、返す値の型(クラス)で関数を宣言する
class samp {
char s[80];
public:
void show() { cout << s << "\n"; }
void set(char *str) { strcpy(s, str); }
};
samp input()
{
char s[80];
samp str;
cout << "文字列の入力: ";
cin >> s;
str.set(s);
return str;
}
samp型のオブジェクトを返す関数input
13.Dec.2004
Object Oriented Language - Y.Nagasaka: [email protected]
9
フレンド関数の概要(1)
 フレンド関数(Friend Function)
 関数をあるクラスのメンバにすることなく、関数からその
クラスの非公開(private)メンバにアクセス対場合に使用す
る
 フレンド関数の用途
 演算子のオーバーロード
 ある種の入出力関数
 1つの関数から2つ以上の別々のクラスの非公開メンバへア
クセス
 フレンド関数の宣言
 アクセスを許可するクラスのpublicエリアに宣言をする
 friend 関数の型 関数名;
 例
friend int isfactor(myclass ob);
13.Dec.2004
Object Oriented Language - Y.Nagasaka: [email protected]
10
フレンド関数の概要(2)
 フレンド関数の例
#include <iostream>
using namespace std;
class myclass {
int n, d;
public:
myclass(int i,int j){
n = i; d = j; }
// myclassのフレンドを宣言する
friend int isfactor(myclass ob);
};
int main()
{
myclass ob1(10, 2), ob2(13, 3);
if(isfactor(ob1)) cout << "2は10の因数\n";
else cout << "2は10の因数ではない\n";
if(isfactor(ob2)) cout << "3は13の因数\n";
else cout << "3は13の因数ではない\n";
return 0;
int isfactor(myclass ob)
{
if(!(ob.n % ob.d)) return 1;
else return 0;
}
// isfactor()関数は、dがnの因数で
// あれば真を返す
}
isfactorはmyclassのメンバ関数ではな
いので、ob1.isfactor; とは書かない
frined関数からprivate属性にアクセスするためには、そのオ
ブジェクトを指定しなければならない (例 ob.n)
13.Dec.2004
Object Oriented Language - Y.Nagasaka: [email protected]
11
フレンド関数の概要(3)
#include <iostream>
using namespace std;
class truck; //前方宣言(宣言前に使うため)
class car {
int passengers;
int speed;
public:
car(int p, int s) {
passengers = p; speed = s; }
friend int sp_greater(car c, truck t);
};
class truck {
int weight;
int speed;
public:
truck(int w, int s) {
weight = w, speed = s; }
friend int sp_greater(car c, truck t);
};
int sp_greater(car c, truck t)
{return c.speed - t.speed;}
int main(){
int t;
car c1(6, 55), c2(2, 120);
truck t1(10000,55), t2(20000,72);
cout << "c1とt1を比較:\n";
t = sp_greater(c1, t1);
if(t<0)
cout << "トラックが速い\n";
else if(t==0)
cout << "速度は同じ\n";
else cout << "Car is faster.\n";
cout << "\nc2とt2を比較:\n";
t = sp_greater(c2, t2);
if(t<0) cout << "トラックが速い\n";
else if(t==0)
cout << "速度は同じ\n";
else
cout << "乗用車が速い\n";
return 0;
}
sp_greater関数
carの速度がtruckよりも速い場合は正の値、同じであれば0、遅い場合は負を返す
13.Dec.2004
Object Oriented Language - Y.Nagasaka: [email protected]
12
オブジェクトの配列(1)
 オブジェクトは変数であり、ほかの方の偏すと同じ
機能と属性を持っている
 したがって、変数と同じように配列の宣言が可能で
ある
#include <iostream>
using namespace std;
int main() {
samp ob[4];
int i;
class samp { //sampクラスの宣言
int a;
public:
void set_a(int n) { a = n; }
int get_a() { return a; }
};
// 配列宣言
for(i=0; i<4; i++)
ob[i].set_a(i);
for(i=0; i<4; i++)
cout << ob[i].get_a( );
cout << "\n";
return 0;
}
13.Dec.2004
Object Oriented Language - Y.Nagasaka: [email protected]
13
オブジェクトの配列(2)
 コンストラクタを利用して初期化する
#include <iostream>
using namespace std;
class samp{ //sampクラスの宣言
int a;
public:
void samp(int n)
int get_a() { return a; }
};
samp::samp(int n){
a = n;
}
//引数1つのコンストラクタ関数
int main() {
samp ob[4]={-1,-2,-3,-4};
// コンストラクタによる初期化
int i;
for(i=0; i<4; i++)
ob[i].set_a(i);
for(i=0; i<4; i++)
cout << ob[i].get_a( );
cout << "\n";
return 0;
}
 初期化時にコンストラクタを呼び出す

samp ob[4]={samp(-1), samp(-2), samp(-3), samp(-4)};
 1つの引数しかとらないコンストラクタの場合は簡略
化することができる

13.Dec.2004
samp ob[4]={-1,-2,-3,14};
Object Oriented Language - Y.Nagasaka: [email protected]
14
オブジェクトのポインタ
 ポインタを利用してオブジェクトにアクセスが可能
 通常の「 . 」演算子の代わりに「->」演算子が使わ
れる
#include <iostream>
using namespace std;
class samp {
int a, b;
public:
samp(int n, int m)
{a = n; b = m;} //コンストラクタ
int get_a() { return a; }
int get_b() { return b; }
};
13.Dec.2004
int main() {
samp ob[4] = {
samp(1, 2),
samp(3, 4),
samp(5, 6),
samp(7, 8)
};
int i;
samp *p;
p = ob; // 配列の開始アドレスを取得する
for(i=0; i<4; i++) {
cout << p->get_a() << ' ';
cout << p->get_b() << "\n";
p++; // 次のオブジェクトに進む
}
cout << "\n";
return 0;
}
Object Oriented Language - Y.Nagasaka: [email protected]
15
thisポインタ
 呼び出しを行ったオブジェクトを参照するthisとい
う特別なポインタがある
#include <iostream>
#include <cstring>
using namespace std;
class inventory {
char item[20];
double cost;
int on_hand;
public:
inventory(char *i, double c, int o){
strcpy(this->item, i);
this->cost = c;
this->on_hand = o;
}
void show();
};
13.Dec.2004
void inventory::show() {
cout << this->item;
cout << ": $" << this->cost;
cout << " 在庫: " << this->on_hand
<< "\n";
}
int main(){
inventory ob("レンチ", 4.95, 4);
ob.show();
return 0;
}
Object Oriented Language - Y.Nagasaka: [email protected]
16
newとdelete
 C言語ではメモリを動的に割り当てるためには
malloc関数を開放するためにはfree関数を使用する。
 C++ではnewとdeleteをしようする。
 例:
 typeクラスの領域を確保しポインタをp-varに割り当てる
 p-var = new type;
 p-varの解法
 delete p-var;
 typeクラスの領域を確保しポインタをp-varに割り当てる。
その際に、初期値を与える
 p-var = new type(initial value);
 配列を割り当て、その先頭ポインタを渡す
 p-var = new type[size];
13.Dec.2004
Object Oriented Language - Y.Nagasaka: [email protected]
17
newとdelete
// 動的変数を初期化する例
#include <iostream>
using namespace std;
int main()
{
int *p;
p = new int(9); // 初期値として9を格納する
if(!p) {
cout << "メモリ割り当てエラー\n";
return 1;
}
cout << "pが指している整数型は: " << *p << "\n";
delete p;
// メモリを解放する
return 0;
}
13.Dec.2004
Object Oriented Language - Y.Nagasaka: [email protected]
18
課題1
 教科書p.82の「前章の理解度チェック」をテ
キストファイルで作成し、提出しなさい。
13.Dec.2004
Object Oriented Language - Y.Nagasaka: [email protected]
19
課題2
 課題1を拡張して、円の面積を返すメンバ関数を追加
したプログラムを作成しなさい(oo21-2.cc)。
Circle
int main() {
int r;
double area;
Circle circle1;
circle1.setR(7);
r = circle1.getR();
cout << “circle1: r=“
<< r << “\n”;
cout << “The area is”
<<circle1.getArea() << “\n”;
-r: int
+setR(rr: int): void
+getR(): int
+getArea(): double
}
13.Dec.2004
Object Oriented Language - Y.Nagasaka: [email protected]
20
コンパイルと実行
 まずはじめに
一度実行すればよい
 作業ディレクトリの作成
$ mkdir ~/wrk/
$ mkdir ~/wrk/oo/
 次に




作業ディレクトリへの移動
プログラミング
コンパイル・リンク
実行
$ cd ~/wrk/oo
$ vi oo20-1.cc
$ g++ -o oo20-1 oo20-1.cc
$ ./oo20-1
* C++言語プログラムのファイル名は、.cc でなければならない
注
意
13.Dec.2004
* プログラムが終了しなくなったら
Ctrl キーを押しながら c
を押して強制終了すること
Object Oriented Language - Y.Nagasaka: [email protected]
21