複素数クラスの例
隠蔽化と基本的なオブジェクト指向の練習課題として、複素数クラスをあげる。ここでは、複素数の加算・乗算を例に説明をするので、減算・除算などの処理を記述することで、クラスの扱いに慣れてもらう。
直交座標系の複素数クラス
#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 ; }