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

本文详细介绍了C++中复数类(complex.h)的构造函数、常量属性、运算符重载(包括友元函数),以及如何正确使用const和赋值操作符。重点讨论了左值与右值在重载运算符中的应用和友元函数在某些场景下的优势。
摘要由CSDN通过智能技术生成

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 <iostream>
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 <iostream>
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 <cmath>

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;
}

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值