ホーム » スタッフ » 斉藤徹 » 講義録 » オブジェクト指向 » 複素数クラスでre-imとr-thのコンストラクタ

2022年6月
 1234
567891011
12131415161718
19202122232425
2627282930  

検索・リンク

複素数クラスでre-imとr-thのコンストラクタ

複素数クラスの課題で、直交座標系のコンストラクタと曲座標系のコンストラクタを作りたいとの質問。でも、以下のようなコンストラクタでは、どちらも Complex( double , double ) であり、区別できない。

class Complex {
private:
    double re , im ;
public:
    Complex( double x , double y ) // コンストラクタ
      : re( x ) , im( y ) {}
    Complex( double r , double th )
      // Complex(double,double)では直交座標系のコンストラクタと区別できない。
      : re( r * cos( th ) ) , im( r * sin( th ) ) {}
    // Complex( double r , double th ) { // これもダメ...
    //     return Complex( r * cos(th) , r * sin(th) ) ;
    // }

    // static は、静的メンバ関数(オブジェクトに対してのメソッドではない)
    static Complex complex_rth( double r , double th ) {
        return Complex( r * cos(th) , r * sin(th) ) ;
    }
} ;

int main() {
    Complex a( 1.0 , 1.0 ) ;
    Complex b = Complex::complex_rth( 1 , 45.0/180.0*3.14 ) ;
    a.print() ; 
    b.print() ;
    return 0 ;
}

色々な書き方はあると思うけど、static Complex Complex::complex_rth( double r , double th ) ; を宣言するのが自然かな…と思ったけど、初期化が Complex a = Complex::complex_rth( 1 , 2 ) ; みたいに書くことになってちょっとダサい。”Complex::” のクラス限定子が邪魔っぽいけど、関数の名前空間を不必要に使わないという意味ではいいのかもしれないが。 C++ の complex クラスを見たら、以下のように使えるようになっていた。なるほど。

class Complex {
private:
    double re , im ;
public:
    Complex( double x , double y ) : re( x ) , im( y ) {}
    void print() const { printf( "%lf+j%lf\n" , re , im ) ; }
} ;

// 曲座標系のコンストラクタ? (正確に言えばコンストラクタではない)
inline Complex polar( double r , double th ) {
    return Complex( r * cos( th ) , r * sin( th ) ) ;
} ;

int main() {
    Complex a( 1 , 2 ) ;
    Complex b = polar( 3 , 30.0 / 180.0 * 3.141592 ) ;
    Complex c( polar( 3 , 30.0 / 180.0 * 3.141592 ) ) ;
      // こっちの書き方の方がコンストラクタを使ってるっぽく見える。
      // デフォルトコピーコンストラクタが使われている。
    a.print() ;
    b.print() ;
    c.print() ;
    return 0 ;
}