1
クラス
Class
(3)メンバ関数と演算子のオーバロード
上級プログラミング 講義資料
成蹊大学理工学部 情報科学科
2多重定義(オーバロード)
関数のオーバロード
C++の関数では、
シグニチャ
(関数名,引数の
型および個数のこと)が異なることによって、同
名の関数が複数存在することが出来る。
演算子のオーバロード
四則演算子をはじめとする演算子を、新たに定
義したクラスを取り扱うように多重定義すること
が出来る。
3
演算子のオーバロード使用以前
例:複素数クラス
Complexを定義できたとする
と、その使い方は・・・
int main() { Complex x,y,z; x.input(); // 複素数xの入力 y.input(); // 複素数yの入力 z= x.add(y); // xにyを加えた複素数をzに代入 z.print(); // zを表示 cout << endl; }加算のわりには不自然な記法。
z = x+y
; と書けないか?
4クラス
Complexの定義の例
class Complex {double real, imaginary; // 実数部realと虚数部imaginary public:
Complex(double a=0, double b=0){ real=a; imaginary=b;
}
void input(){
cout << "実数部と虚数部を入力せよ-->"; cin >> real >> imaginary;
}
void print(){ cout << real;
if(imaginary>0) cout << "+";
cout << imaginary << “i”; // a+biまたはa-biの形式で表示 }
Complex add(Complex k){
return Complex(real+k.real, imaginary+k.imaginary); }
5
演算子のオーバロード
演算子は関数の特殊ケース
例: +演算子
→ operator+ という名の関数
二項演算子における2つの解釈
obj1 + obj2
【解釈1】
operator+をobj1のクラスのメンバ関数と解釈
obj1.operator+(obj2)
と等価
obj1:第1オペランド obj2:第2オペランド【解釈2】
両オペランドともoperator+の引数と解釈
operator+(obj1, obj2)
と等価
この場合、operator+はメンバ関数とはならない。
6演算子のオーバロード使用後
class Complex {double real, imaginary; // 実数部realと虚数部imaginary public:
Complex(double a=0, double b=0){ real=a; imaginary=b;
}
void input(){
cout << "実数部と虚数部を入力せよ-->"; cin >> real >> imaginary;
}
void print(){ cout << real;
if(imaginary>0) cout << "+";
cout << imaginary << “i”; // a+biまたはa-biの形式で表示 }
Complex operator+(Complex k){
return Complex(real+k.real, imaginary+k.imaginary); }
7
演算子のオーバロード使用以後
例:複素数クラス
Complexを定義できたとする
と、その使い方は・・・
int main() { Complex x,y,z; x.input(); // 複素数xの入力 y.input(); // 複素数yの入力 z= x+y; // xにyを加えた複素数をzに代入 z.print(); // zを表示 cout << endl; }z = x.operator+(y)
;
と書いても良いが、そんな書き方をする人はいない・・・ 8演算子をオーバロードする場合の注意
オーバロード可能な演算子
(,),[,],->,*,&,++,--,-,~,!,/,%,+,<<,>>, <,>,<=,>=,==,!=,^,|,&&,||,=,+=,*=,/=,-=,%= などオーバロード不可能な演算子
. :: .* ?: sizeof代入演算子=について
=は、同じクラスのオブジェクト同士であれば代入できるように オーバロードされている演算子なので、「代入」目的以外で使わ ない限り、ユーザがオーバロードする必要はない。優先順位
オーバロードされた演算子でも、その演算子の元の優先順位や 結合規則(左結合性、右結合性、結合性なし)は変えることがで きない。9
演算子の関数形の例
配列演算子[]の例
rType operator[](dType darg);
rType:リターン型、 dType:仮引数の型 インクリメント演算子・デクリメント演算子 前置の++の場合 rType operator++(); //そのクラスのメンバ関数の場合 rType operator++(AClass&); //Aclassのメンバ関数でない場合の例 後置の++の場合 rType operator++(int); //そのクラスのメンバ関数の場合 rType operator++(AClass&,int); //Aclassのメンバ関数でない場合の例
他の演算子のオーバロードは?
int main()
{
Complex x,y,z;
x.input();
y.input();
z= x.add(y);
z.print();
cout << endl;
}
int main()
{
Complex x,y,z;
}
cin >> x >> y;
cout << z << endl;
z= x+y;
演算子を用いた、自然な記述複素数クラス
x+y以外も上記のようにできるのだろうか?
11
cin(標準入力)は実行環境に1つなので、参照変数で受け渡す。
複素数クラスComplexのメンバ関数ではない!演算子の関数表現
cin
>>
x >> y;
入力演算子 >>
operator>>
(cin, x)
istream& operator>>( istream& , Complex& );
この関数のプロトタイプはどうなるか?
cinを受け取り、 cinを返す。 12演算子の関数表現(2)
cout
<<
z << endl;
出力演算子 <<
operator<<
(cout, z)
この関数のプロトタイプはどうなるか?
cout(標準出力)は実行環境に1つなので、参照変数で受け渡す。
複素数クラスComplexのメンバ関数ではない!ostream& operator<<( ostream& , Complex );
coutを受け取り、 coutを返す。
13
cin, coutの参照渡しについて
main
istreamクラスのオ ブジェクト ostreamクラスの オブジェクト cout<<y; cin>>x; 14cin, coutの参照渡しについて
main関数
cout<<y; cin>>x; operator>>operator>>(istream inst, ・・・
15
cin, coutの参照渡しについて
main関数
cout<<y; cin>>x; operator>>istream& operator>>(istream &inst, ・・・){ ・・・; return inst; } operator>>関数は cin自体をinstという名前で使用する。 そして最後に使用したinst、つまりcinを返す 。