複素数クラスの例
隠蔽化と基本的なオブジェクト指向の練習課題として、複素数クラスをあげる。ここでは、複素数の加算・乗算を例に説明をするので、減算・除算などの処理を記述することで、クラスの扱いに慣れてもらう。
直交座標系の複素数クラス
#include <stdio.h>
#include <math.h>
// 直交座標系の複素数クラス
class Complex {
private:
double re ; // 実部
double im ; // 虚部
public:
void print() {
printf( "%lf + j%lf¥n" , re , im ) ;
}
Complex( double r , double i ) // コンストラクタで要素の
: re( r ) , im( i ) { // 初期化はこのように書いてもいい
} // re = r ; im = i ; の意味
Complex() // デフォルトコンストラクタ
: re( 0.0 ) , im( 0.0 ) {
}
void add( Complex z ) {
// 加算は、直交座標系だと極めてシンプル
re = re + z.re ;
im = im + z.im ;
}
void mul( Complex z ) {
// 乗算は、直交座標系だと、ちょっと煩雑
double r = re * z.re - im * z.im ;
double i = re * z.im + im * z.re ;
re = r ;
im = i ;
}
double get_re() {
return re ;
}
double get_im() {
return im ;
}
double get_abs() { // 絶対値
return sqrt( re*re + im*im ) ;
}
double get_arg() { // 偏角
return atan2( im , re ) ;
}
} ; // ←何度も繰り返すけど、ここのセミコロン忘れないでね
int main() {
// 複素数を作る
Complex a( 1.0 , 2.0 ) ;
Complex b( 2.0 , 3.0 ) ;
// 複素数の計算
a.print() ;
a.add( b ) ;
a.print() ;
a.mul( b ) ;
a.print() ;
return 0 ;
}
C++と演算子のオーバーロード
C++では、演算子のオーバーロードという機能がある。前の例では、複素数の計算で a.add( b ) といった呼び出しで 複素数の a + b の計算をして、計算結果が a に格納されていた。でもやっぱり、c = a + b ; と書けたらすごく便利。
ということで、C++ では、関数名を書く欄に、operator 演算子( 右辺 ) { … } という書き方ができる。
関数の返り値の前に inline を書くと、開いたサブルーチンにしてくれる。
仮引数宣言の const は、引数に対して修正が行われないことを示す。
型 関数名( 仮引数, … ) const { … } としてメソッドを定義すると、オブジェクトを書き換えないことを明示できる。
#include <stdio.h>
#include <math.h>
// 直交座標系の複素数クラス
class Complex {
private:
double re ; // 実部
double im ; // 虚部
public:
Complex( double r , double i ) // コンストラクタで要素の
: re( r ) , im( i ) { // 初期化はこのように書いてもいい
} // re = r ; im = i ; の意味
Complex() // デフォルトコンストラクタ
: re( 0.0 ) , im( 0.0 ) {}
// C++ではそのクラス専用の演算子を定義できる(演算子のオーバーロード)
Complex operator+( const Complex &z ) const {
// 加算は、直交座標系だと極めてシンプル
return Complex( re + z.re , im + z.im ) ;
}
Complex operator*( const Complex &z ) const {
// 乗算は、直交座標系だと、ちょっと煩雑
double r = re * z.re - im * z.im ;
double i = re * z.im + im * z.re ;
return Complex( r , i ) ;
}
// getter メソッド
inline double get_re() const { return re ; }
inline double get_im() const { return im ; }
double get_abs() const { return sqrt( re*re + im*im ) ; } // 絶対値
double get_arg() const { return atan2( im , re ) ; } // 偏角
void print() {
printf( "%lf + j%lf\n" , get_re() , get_im() ) ;
}
void print_polar() {
printf( "%lf ∠ %lf\n" , get_abs() , get_arg() / 3.141592 * 180.0 ) ;
}
} ; // ←何度も繰り返すけど、ここのセミコロン忘れないでね
int main() {
// 複素数を作る
Complex a( 1.0 , 2.0 ) ;
Complex b( 2.0 , 3.0 ) ;
// 複素数の計算
Complex c = a + b ;
Complex d = a * b ;
// 結果の表示
c.print() ;
d.print() ;
c.print_polar() ;
d.print_polar() ;
return 0 ;
}