本例主要对类模板(第一次用,呵呵!), 操作符的重载, 友元(真心不好用,慎用,虽然形式简单,但会给你带来不少的麻烦)等知识的复习。调试该程序花了不少时间,也让我学了很多东西,也深知很多东西虽然知道,但是去实践了你才感觉这些东西你是否深刻理解。学东西还是”深拷贝”的好!该程序做完花了3个多小时,其中有绝大多数时间用于调试,期间遇到的错误有VC版本本身的问题,也有各种其他的问题。本程序未参照任何复数相关的任何程序,难免有疏忽和不恰当的地方,请指正!
代码如下:
在complex.h主要实现类的定义及友元的实现, 因为成员函数比较短所以在类中一并定义了。
#ifndef COMPLEX_H_
#define COMPLEX_H_
#include <iostream>
#include <cmath>
template <class T>
class Complex
{
private:
T m_Real;
T m_Img;
public:
Complex() { m_Real = 0; m_Img = 0;}
Complex(T real, T img) { m_Real = real; m_Img = img; }
Complex GetComplexConjugate(){ return Complex(m_Real, -1 * m_Img); }
T GetReal() { return m_Real; }
T GetImg() { return m_Img; }
/* overloading the arithmetic operators */
friend Complex operator+ (const Complex & cComplexFirst, const Complex & cComplexSecond);
friend Complex operator- (const Complex & cComplexFirst, const Complex & cComplexSecond);
friend Complex operator* (const Complex & cComplexFirst, const Complex & cComplexSecond);
friend Complex operator/ (Complex & cComplexFirst, Complex & cComplexSecond);
/****************************************/
/* overloading the I/O operators */
friend std::ostream& operator<< (std::ostream &os, const Complex & cComplexResult); // for output
friend std::istream& operator>> (std::istream &is, Complex & cComplexInput); // for input
/* overloading the comparison operators */
friend bool operator >= (const Complex & cComplexFirst, const Complex & cComplexSecond);
friend bool operator <= (const Complex & cComplexFirst, const Complex & cComplexSecond);
friend bool operator == (const Complex & cComplexFirst, const Complex & cComplexSecond);
};
#endif
template <class T>
Complex<T> operator+ (const Complex<T> & cComplexFirst, const Complex<T> & cComplexSecond)
{
return Complex<T>((cComplexFirst.m_Real + cComplexSecond.m_Real), (cComplexFirst.m_Img + cComplexSecond.m_Img));
}
template <class T>
Complex<T> operator- (const Complex<T> & cComplexFirst, const Complex<T> & cComplexSecond)
{
return Complex<T>((cComplexFirst.m_Real - cComplexSecond.m_Real), (cComplexFirst.m_Img - cComplexSecond.m_Img));
}
template <class T>
Complex<T> operator* (const Complex<T> & cComplexFirst, const Complex<T> & cComplexSecond)
{
return Complex<T>((cComplexFirst.m_Real * cComplexSecond.m_Real - cComplexFirst.m_Img * cComplexSecond.m_Img),
(cComplexFirst.m_Real * cComplexSecond.m_Img + cComplexFirst.m_Img * cComplexSecond.m_Real));
}
template <class T>
Complex<T> operator/ (Complex<T> & cComplexFirst, Complex<T> & cComplexSecond)
{
if (cComplexSecond.m_Real == 0 && cComplexSecond.m_Img == 0)
{
std::cerr << "Divide zero!@@@";
return Complex<T>(-10000, -10000); // using -10000 for divide zero
}
else if (cComplexFirst.m_Real == 0 && cComplexSecond.m_Img == 0)
return Complex<T>(0, 0);
else
{
T tReal = pow(abs(cComplexSecond.m_Real), 2) + pow(abs(cComplexSecond.m_Img), 2);
cComplexFirst.m_Real = (1 / tReal) * cComplexFirst.m_Real;
cComplexFirst.m_Img = (1 / tReal) * cComplexFirst.m_Img;
cComplexSecond.m_Real = (1 / tReal) * cComplexSecond.m_Real;
cComplexSecond.m_Img = (1 / tReal) * cComplexSecond.m_Img;
return cComplexFirst * (cComplexSecond.GetComplexConjugate());
}
}
template<class T>
std::ostream& operator<< (std::ostream & os, const Complex<T>& cComplexResult)
{
os << "(real, img) = (" << cComplexResult.m_Real << " , " << cComplexResult.m_Img << ")"<< std::endl;
return os;
}
template<class T>
std::istream& operator>> (std::istream &is, Complex<T> & cComplexInput)
{
// first is RealPart, second input is ImgPart
is >> cComplexInput.m_Real;
is >> cComplexInput.m_Img;
return is;
}
template <class T>
bool operator >= (const Complex<T> & cComplexFirst, const Complex<T> & cComplexSecond)
{
if (cComplexFirst.m_Real == 0 && cComplexSecond.m_Img == 0)
{ // if both Complex objects' real part is zero, we will make comparison using imag part
return (cComplexFirst.m_Img > cComplexSecond.m_Img);
}
else if (cComplexFirst.m_Img == 0 && cComplexSecond.m_Img == 0)
{
return (cComplexFirst.m_Real > cComplexSecond.m_Real);
}
else
{ // normal condition : the length of using function sqrt
return ((pow(abs(cComplexFirst.m_Real), 2) + pow(abs(cComplexFirst.m_Img), 2))
>= (pow(abs(cComplexSecond.m_Real), 2) + pow(abs(cComplexSecond.m_Img), 2)));
}
}
template <class T>
bool operator <= (const Complex<T> & cComplexFirst, const Complex<T> & cComplexSecond)
{
return ((pow(abs(cComplexFirst.m_Real), 2) + pow(abs(cComplexFirst.m_Img), 2))
<= (pow((cComplexSecond.m_Real), 2) + pow((cComplexSecond.m_Img), 2)));
}
template <class T>
bool operator == (const Complex<T> & cComplexFirst, const Complex<T> & cComplexSecond)
{
return ((pow(abs(cComplexFirst.m_Real), 2) + pow(abs(cComplexFirst.m_Img), 2)
== pow(abs(cComplexSecond.m_Real), 2) + pow(abs(cComplexSecond.m_Img), 2)));
}
在testmain.cpp中主要进行测试工作!
代码如下:
#include "complex.h"
#include <iostream>
int main()
{
Complex<float> cComplexFirst(31.2f, 5.0f);
Complex<float> cComplexSecond(10.0f, 10.0f);
Complex<float> cComplexResult(0,0); // initialization
cComplexResult = cComplexFirst + cComplexSecond; // add
std::cout << "add result: " << cComplexResult; // output operator test
Complex<float> cComplexTemp(0, 0);
std::cin >> cComplexTemp; // input operator test
std::cout << "multiply result: " << cComplexResult * cComplexTemp; // multiply
if (cComplexResult == cComplexTemp) // should compare before do operator(/)
//because in the divide function the argument will be changed.
{
std::cout << "output is equal!" << std::endl;
}
else
{
std::cout << "output is not equal!" << std::endl;
}
std::cout << "divde reult: " << cComplexResult / cComplexTemp; // divide
if (cComplexFirst >= cComplexSecond)
{
std::cout << "Complex first bigger!" << std::endl;
}
else
{
std::cout << "Complex second bigger!" << std::endl;
}
return 0;
}
测试结果: