C++ Complex类实现 - 操作符重载、友元

complex.h

About constructor

complex(double r = 0, double i = 0)
        : re (r), im (i)
    { }

 something in " : " => happen with initializing

complex(double r = 0, double i = 0)
{ 
    this->re = r;
    this->im = i;
}

something in " { } " => happen after initializing, is assignment.

That's the difference. 

Paradigm

something about const and &

const

double real() const { return re; }

Ask yourself frequently whether should be added the const or not, it's up to whether existing everything never changed or not.

&

inline complex
operator / (const complex& x, const complex& y)
{
    complex temp = ( x * conj(y) ) / (y * conj(y)).real();
    return complex (temp.real(), temp.imag());
}

// 上下代码不同写法可以看出friend起到的作用

inline complex&
complex::operator /= (const complex& r)
{
    complex temp = (r * conj(r)).re / (*this) * conj(r);
    this->re = temp.re;
    this->im = temp.im;
    return *this;
}

complex () => typename () => to creator a local object in this scope without name. 

we prefer to using & (it's beneficial for space saving) as long as there is not a local object

{
...
complex& operator += (const complex&);
...
friend complex& __doapl(complex*, const complex&);
...
}

inline complex&
complex::operator += (const complex& r)
{
    return __doapl (this, r);
}

The function of " operator += " is the member function of class complex,

but it was declared in the class,

and defined outside the class => so you should use classname:: to associate with.

The function " __doapl " is a friend function,

it is not a member function, ( do not need to use classname:: )

but can visit the private member variables.

operator overloading

inline complex
operator / (const complex& x, const complex& y)
{
    complex temp = ( x * conj(y) ) / (y * conj(y)).real();
    return complex (temp.real(), temp.imag());
}

// 上下代码不同写法可以看出friend起到的作用

inline complex&
complex::operator /= (const complex& r)
{
    complex temp = (r * conj(r)).re / (*this) * conj(r);
    this->re = temp.re;
    this->im = temp.im;
    return *this;
}

if you define the operator overloading function in the class, then the left value during operating must be the object of this class.

Sometimes, It may good.

But, Maybe it can not meet your need.

For example:

#include 
std::ostream&
operator << (std::ostream& os, const complex& x)
{
    return os << "( " << x.real() << " , " << x.imag() << " )";
}

the correct way permit the code: cout << c1

otherwise, you should write something like c1 << cout

That is something you shoule pay attention.

#ifndef __MYCOMPLEX__
#define __MYCOMPLEX__

class complex;
// assignment plus
complex&
__doapl (complex* ths, const complex& r);
// assignment minus
complex&
__doami (complex* ths, const complex& r);
// assignment multiply
complex&
__doaml (complex* ths, const complex& r);
// conjugate complex
complex
conj (const complex& x);
// norm of complex
double
norm (const complex& x);


class complex {
public:
    complex(double r = 0, double i = 0)
        : re (r), im (i)
    { }
//    养成 无变量变化就加上const 的习惯
//如果设计函数者不加const 使用函数的人用const 编译器会报错 这就是设计函数者的责任
    double real() const { return re; }
    double imag() const { return im; }
//    写成成员函数 可以对左值作用
    complex& operator += (const complex&);
    complex& operator -= (const complex&);
    complex& operator *= (const complex&);
    complex& operator /= (const complex&);

private:
    double re, im;

    friend complex& __doapl(complex*, const complex&);
    friend complex& __doami(complex*, const complex&);
    friend complex& __doaml(complex*, const complex&);
};

inline complex&
__doapl(complex* ths, const complex& r)
{
    ths->re += r.re;
    ths->im += r.im;
    return *ths;
}

inline complex&
complex::operator += (const complex& r)
{
    return __doapl (this, r);
}

inline complex
operator + (const complex& x, const complex& y)
{
    return complex ( x.real() +  y.real(),
                     x.imag() + y.imag() );
}

inline complex
operator + (const complex& x, double y)
{
    return complex ( x.real() + y, x.imag());
}

inline complex
operator + (double x, const complex& y)
{
    return complex ( x + y.real(), y.imag());
}

inline complex&
__doami (complex* ths, const complex& r)
{
    ths->re -= r.re;
    ths->im -= r.im;
    return *ths;
}

inline complex&
complex::operator -= (const complex& r)
{
    return __doami(this, r);
}

inline complex
operator - (const complex& x, const complex& y)
{
    return complex (x.real() - y.real(),
                    x.imag() - y.imag());
}

inline complex
operator - (const complex& x, double y)
{
    return complex (x.real() - y, x.imag());
}

inline complex
operator - (double x, const complex& y)
{
    return complex (x - y.real(), y.imag());
}

complex&
__doaml (complex* ths, const complex& r)
{
    ths->re = ths->re * r.re - ths->im * r.im;
    ths->im = ths->re * r.im + ths->im * r.re;
    return *ths;
}

inline complex&
complex::operator *= (const complex& r)
{
    return __doaml(this, r);
}

inline complex
operator * (const complex& x, const complex& y)
{
    return complex (x.real() * y.real() - x.imag() * y.imag(),
                     x.real() * y.imag() + x.imag() * y.real());
}

inline complex
operator * (const complex& x, double y)
{
    return complex (x.real() * y, x.imag() * y);
}

inline complex
operator * (double x, const complex& y)
{
    return complex (x * y.real(), x * y.imag());
}

inline complex
operator / (const complex& x, double y)
{
    return complex (x.real() / y, x.imag() / y);
}

inline complex
operator / (double x, const complex& y)
{
    return complex (x / y.real(), x / y.imag());
}

complex
conj (const complex& x)
{
    return complex (x.real(), -x.imag());
}

inline complex
operator / (const complex& x, const complex& y)
{
    complex temp = ( x * conj(y) ) / (y * conj(y)).real();
    return complex (temp.real(), temp.imag());
}

// 上下代码不同写法可以看出friend起到的作用

inline complex&
complex::operator /= (const complex& r)
{
    double denominator = (r * conj(r)).re;
    complex numerator = (*this) * conj(r);
    complex temp = numerator / denominator;
    this->re = temp.re;
    this->im = temp.im;
    return *this;
}

#include 
std::ostream&
operator << (std::ostream& os, const complex& x)
{
    return os << "( " << x.real() << " , " << x.imag() << " )";
}

inline bool
operator == (const complex& x, const complex& y)
{
    return x.real() == y.real() && x.imag() == y.imag();
}

inline bool
operator == (const complex& x, double y)
{
    return x.real() == y && x.imag() == 0;
}

inline bool
operator == (double x, const complex& y)
{
    return x == y.real() && y.imag() == 0;
}

inline bool
operator != (const complex& x, const complex& y)
{
    return x.real() != y.real() || x.imag() != y.imag();
}

inline bool
operator != (const complex& x, double y)
{
    return x.real() != y || x.imag() != 0;
}

inline bool
operator != (double x, const complex& y)
{
    return x != y.real() || y.imag() != 0;
}

#include 

inline complex
polar (double r, double t)
{
    return complex ( r * cos(t), r * sin(t) );
}

inline double
norm (const complex& x)
{
    return sqrt(x.real() * x.real() +
                x.imag() * x.imag());
}

#endif

complex_test.cpp

Using " " to include file writen by yourself, < > for standard library.

#include "complex.h"

int main()
{
	complex c1(1, 1);
	complex c2(2, 1);
	std::cout << "c1: "<< c1 << std::endl;
	std::cout << "c2: "<< c2 << std::endl;
	c1 += c2;
	std::cout << "c1: "<< c1 << std::endl;
	c2 -= c1;
	std::cout << "c2: "<< c2 << std::endl;
	std::cout << "c1 * c2: "<< c1*c2 << std::endl;
	return 0;
}

你可能感兴趣的:(c++,开发语言)