C/C++ 自定義複數運算類別 範例

C/C++ 自定義複數運算類別 範例

C/C++ 自定義複數運算類別 範例


資料來源: https://mp.weixin.qq.com/s/VwogODPifOCKgSKVQE8lcA


線上執行: https://www.runoob.com/try/runcode.php?filename=helloworld&type=cpp

https://www.tutorialspoint.com/compile_cpp_online.php


功能:自定義復數類型,實現複數的加、減、乘、除、求共軛複數、乘方、開方等運算。

涉及到的基礎知識點有:

    01.運算符重載(+,-,*,/, <<, ^, ==, != 等運算符的重載)

    02.友宜函數(友元函數可訪問類的私有屬性)

    03.函數返回指向數組的指針。此例中數組的元素是類的對象。

    04.左值引用與右值引用

    05.主動拋出異常(使用關鍵字throw)

code:

#include <iostream>
#include <cmath>
using namespace std;


class Division_by_zero:exception{};

class NegativeValue:exception{};


class Complex
{
//类的友元函数,让该函数可以访问类的私有属性
friend ostream & operator<<(ostream& out, Complex& c);//左值引用
friend ostream & operator<<(ostream& out, Complex&& c);//右值引用
friend Complex operator*(double k, Complex& c);//左侧数乘 左值引用
friend Complex operator*(double k, Complex&& c);//左侧数乘 右值引用
private:
    double re;
    double im;
    
public:
    Complex()
    {
        re = 0;//实部
        im = 0;//虚部
    }
    
    Complex(double r, double i)
    {
        re = r;//实部
        im = i;//虚部
    }
    
    double get_re()
{
        return re;
    }
    
    double get_im()
{
        return im;
    }
    
    double mag() const//计算幅值
{
        double temp = re*re;
        temp += im*im;
        return sqrt(temp);
    }
    
    double ang() const //计算相位角
{
        return atan2(im, re);
    }
    
    Complex conjugate() const
{
        Complex temp ={0, 0};
        temp.re = this->re;
        temp.im = -this->im;
        return temp;
    }
    
    //重载加号运算符
    Complex operator+(Complex& other) const
    {
        Complex temp ={0, 0};
        temp.re = this->re + other.re;
        temp.im = this->im + other.im;
        return temp;
    }
    Complex operator+(Complex&& other) const //右值引用
    {
        Complex temp ={0, 0};
        temp.re = this->re + other.re;
        temp.im = this->im + other.im;
        return temp;
    }
    
    //重载减号运算符
    Complex operator-(Complex& other) const
    {
        Complex temp ={0, 0};
        temp.re = this->re - other.re;
        temp.im = this->im - other.im;
        return temp;
    }
    Complex operator-(Complex&& other) const //右值引用
    {
        Complex temp ={0, 0};
        temp.re = this->re - other.re;
        temp.im = this->im - other.im;
        return temp;
    }
    
    //重载乘号运算符
    Complex operator*(Complex& other) const
    {
        Complex temp ={0, 0};
        temp.re = this->re * other.re - this->im * other.im;
        temp.im = this->re * other.im + this->im * other.re;
        return temp;
    }
    Complex operator*(Complex&& other) const //右值引用
    {
        Complex temp ={0, 0};
        temp.re = this->re * other.re - this->im * other.im;
        temp.im = this->re * other.im + this->im * other.re;
        return temp;
    }
    
    Complex operator*(double k) const //右侧数乘
    {
        Complex temp ={0, 0};
        temp.re = k * this->re;
        temp.im = k * this->im;
        return temp;
    }
    
    //重载除号运算符
    Complex operator/(Complex& other) const
    {
        double denominator;
        denominator = other.re * other.re + other.im * other.im;
        if(denominator==0)
        {
            throw Division_by_zero();
        }
        Complex temp ={0, 0};
        temp.re = (this->re * other.re + this->im * other.im)/denominator;
        temp.im = (this->im * other.re - this->re * other.im)/denominator;
        return temp;
    }
    
    Complex operator/(Complex&& other) const //右值引用
    {
        double denominator;
        denominator = other.re * other.re + other.im * other.im;
        if(denominator==0)
        {
            throw Division_by_zero();
        }
        Complex temp ={0, 0};
        temp.re = (this->re * other.re + this->im * other.im)/denominator;
        temp.im = (this->im * other.re - this->re * other.im)/denominator;
        return temp;
    }
    
    //幂运算
    Complex operator^(int n) const
    {
        if(n<0)
        {
            throw NegativeValue();
        }
        Complex temp ={0, 0};
        double r = this->mag();
        double theta = this->ang();
        temp.re = cos(n * theta);
        temp.im = sin(n * theta);
        temp = temp * pow(r, n);
        return temp;
    }
    
    //开n次方
    Complex* root(int n) const
{
        if(n<=0)//如果n的类型是 unsigned, 则这句不执行!
        {
            throw NegativeValue();
        }
        const double pi = 3.141592653589793238;
        Complex* p = new Complex[n]; //p指向堆上新建的数组
        Complex temp ={0, 0};
        double r = this->mag();
        double theta = this->ang();
        double theta_new = 0.0;
        double r_new = pow(r, 1.0/n);
        for(int k=0; k<n; k++)
        {
            theta_new = (2.0*k*pi + theta)/n;
            temp.re = r_new * cos(theta_new);
            temp.im = r_new * sin(theta_new);
            p[k] = temp;
        }
        return p;//返回数组指针
    }
    
    //重载等号运算符
    bool operator==(Complex& other) const
    {
        return this->re == other.re && this->im == other.im;
    }
     bool operator==(Complex&& other) const //右值引用
    {
        return (this->re == other.re && this->im == other.im);
    }

    //重载不等于等号运算符
    bool operator!=(Complex& other) const
    {
        return this->re != other.re || this->im != other.im;
    }
     bool operator!=(Complex&& other) const //右值引用
    {
        return this->re != other.re || this->im != other.im;
    }
};


//左移运算符重载,用于自定义打印。只能利用全局函数重载左移运算符
ostream & operator<<(ostream& out, Complex& c)
{
    if(c.im >= 0) out<< c.re <<"+" << c.im <<"j";
    else out<< c.re  << c.im <<"j";
    return out;
}
// 同上,但右值引用
ostream & operator<<(ostream& out, Complex&& c)
{
    if(c.im >= 0) out<< c.re <<"+" << c.im <<"j";
    else out<< c.re  << c.im <<"j";
    return out;
}

//左侧数乘
Complex operator*(double k, Complex& c)
    {
        Complex temp ={0, 0};
        temp.re = k * c.re;
        temp.im = k * c.im;
        return temp;
    }
Complex operator*(double k, Complex&& c)
    {
        Complex temp ={0, 0};
        temp.re = k * c.re;
        temp.im = k * c.im;
        return temp;
    }

int main()
{
    //测试
    Complex c1 ={-1,3};
    Complex c2 ={3,4};
    Complex c3 = c2;
    cout.precision(10);
    cout<<"c1= "<<c1<<endl;
    cout<<"c1.re = "<<c1.get_re()<<endl;
    cout<<"c1.im = "<<c1.get_im()<<endl;
    cout<<"conjugate complex of c1: "<< c1.conjugate() << endl;
    cout<< "4*c1 = " << 4*c1 << endl;
    cout<<"c2= " << c2 << endl;
    cout<<"c3= " << c3 << endl;
    cout<<"c2.mag= "<< c2.mag() <<endl;
    cout<<"c1+c2= " << c1+c2 << endl;
    cout<<"c1-c2= " << c1-c2 << endl;
    cout<<Complex(-1,-3)<<endl;//Complex(-1,-3)是个常量,属于右值
    cout<<Complex(3,5) * Complex(3,5)<<endl;
    cout<<Complex(3,4) / Complex(5,6)<<endl;
    //cout<<Complex(3,4) / Complex(0,0)<<endl;//0做分母
    cout<<(Complex(3,4)^(9))<<endl;
    unsigned n = 9;
    Complex* p = Complex(3,4).root(n);
    cout << Complex(3,4) << "的" << n << "个" << n << "次方根为:" << endl;
    for(unsigned i=0; i<n; i++)
    {
        cout << "第" << (i+1) << "个" << n <<"次方根为:" << p[i] <<endl;
    }
    delete[] p;
    return 0;
}
/*
c1= -1+3j
c1.re = -1
c1.im = 3
conjugate complex of c1: -1-3j
4*c1 = -4+12j
c2= 3+4j
c3= 3+4j
c2.mag= 5
c1+c2= 2+7j
c1-c2= -4-1j
-1-3j
-16+30j
0.6393442623+0.03278688525j
-922077+1721764j
3+4j的9个9次方根为:
第1个9次方根为:1.189471556+0.1229901067j
第2个9次方根为:0.8321315588+0.8587934659j
第3个9次方根为:0.08542795743+1.192757818j
第4个9次方根为:-0.7012483347+0.968617531j
第5个9次方根为:-1.159802738+0.2912503363j
第6个9次方根为:-1.07567255-0.5223961277j
第7个9次方根为:-0.4882232211-1.091607638j
第8个9次方根为:0.3276711787-1.150043802j
第9个9次方根为:0.9902445922-0.6703616903j
*/

發表迴響

你的電子郵件位址並不會被公開。 必要欄位標記為 *