C++

【侯捷】创建一个Complex类

Posted by LudoArt on August 14, 2019

#【侯捷】创建一个Complex类

本文章中涉及的知识点:

  • 构造函数
  • const
  • 操作符重载
  • 友元函数
  • 模板

创建一个complex.h的头文件,将complex类的定义和声明都写在该头文件中。


//防卫式声明

#ifndef __MYCOMPLEX__
#define __MYCOMPLEX__

class complex; 
complex&
    __doapl (complex* ths, const complex& r);


class complex
{
public:
    //构造函数

    complex (double r = 0, double i = 0): re (r), im (i) { }
    complex& operator += (const complex&);
	//任何不会修改数据成员的函数都应该声明为const类型
	
    double real () const { return re; }
    double imag () const { return im; }
private:
    double re, im;

    friend complex& __doapl (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 double
imag (const complex& x)
{
    return x.imag ();
}

inline double
real (const complex& x)
{
    return x.real ();
}

//第一种情况:complex + complex

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

//第二种情况:complex + double

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

//第三种情况:double + complex

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

//第四种情况(只有一个参数,即+complex):在complex前加一个正号

inline complex
operator + (const complex& x)
{
    return x;
}

#endif   //__MYCOMPLEX__

创建一个complex.cpp,测试在complex.h中的定义和声明的complex类。


#include <iostream>
#include "Complex.h"
using namespace std;

//因为没有修改到c里面的内容且不能修改,所以可以引用传参且加上const关键字

ostream&
operator << (ostream& os, const complex& x)
{
    return os << real (x) << "+" << imag (x) << "i";
}

int main()
{
    Complex<int> c1(2, 1);
    Complex<int> c2(4, 0);

    cout << c1 << endl; //2+1i

    cout << c2 << endl; //4+0i

    cout << c1 + c2 << endl; //6+1i

    cout << (c1 += c2) << endl; //6+1i

    cout << (5 + c2) << endl; //9+0i

    return 0;
}

尝试对其增加模板,在写模板类的友元模板函数时遇到了困难,临时的办法是声明与定义直接都写在类中。


#ifndef __MYCOMPLEX__
#define __MYCOMPLEX__

template <typename T>
class Complex {
public:
	Complex(T r = 0, T i = 0) :_real(r), _imag(i) { }
	Complex& operator += (const Complex&);
	T get_real() const { return _real; }
	T get_imag() const { return _imag; }

	//进行友元函数的声明

	//friend Complex& _doapl <T>(Complex *, const Complex&);
	
	friend Complex& _doapl (Complex *ths, const Complex&c)
	{
		ths->_real += c.get_real();
		ths->_imag += c.get_imag();
		return *ths;
	}
private:
	T _real, _imag;
};

//具体写友元函数,但这种写法在编译器里报错,如何解决仍未有结果

//template<typename T>

//inline Complex<T>& _doapl(Complex<T> *ths, const Complex<T> &c)

//{

//	ths->_real += c.get_real();

//	ths->_imag += c.get_imag();

//	return *ths;

//}


template<typename T>
inline Complex<T> & Complex<T>::operator+=(const Complex<T> &c)
{
	return _doapl(this, c);
}

template<typename T>
inline Complex<T> operator + (const Complex<T>& c1, const Complex<T>& c2)
{
	return Complex<T>(c1.get_real() + c2.get_real(), c1.get_imag() + c2.get_imag());
}

template<typename T>
inline Complex<T> operator + (const Complex<T>& c, const T& t)
{
	return Complex<T>(c.get_real() + t, c.get_imag());
}

template<typename T>
inline Complex<T> operator + (const T& t, const Complex<T>& c)
{
	return Complex<T>(c.get_real() + t, c.get_imag());
}

#endif //__MYCOMPLEX__