本例主要对类模板(第一次用,呵呵!), 操作符的重载, 友元(真心不好用,慎用,虽然形式简单,但会给你带来不少的麻烦)等知识的复习。调试该程序花了不少时间,也让我学了很多东西,也深知很多东西虽然知道,但是去实践了你才感觉这些东西你是否深刻理解。学东西还是”深拷贝”的好!该程序做完花了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; }
测试结果: