#【侯捷】创建一个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__