当在一个模板类中,需要使用别的.h头文件中的函数模板时,一定需要在别的.h头文件中加上这样2句话:(否则就是报错!这样的错误你很难发现是啥错,也难以看懂!)
这个小技巧一定要掌握!!!
template<typename T> class 对应模板类的名称;//注意:不需要带上T,否则会报错! //给这个模板类来一个前置声明,否则后续该模板函数用到该类时会识别不出来是哪一个类
rationalt.h:
#ifndef __RATIONALT_H__ #define __RATIONALT_H__ #include<iostream> #include<memory> #include"domultiply.h" using namespace std; template<typename T> class Rationalt{ public: typedef Rationalt<T> RaT; friend const RaT operator*(const RaT& rhs1, const RaT& rhs2){ return doMultiply(rhs1,rhs2); //为了让inline的冲击最小化,必须这么干!(来一个辅助函数do事情!而operator*里面不do任何事情) } public: inline Rationalt(const T& numerator = 0,const T& denominator = 1) :m_Numerator(new int(numerator)),m_Denominator(new int(denominator)){} Rationalt(const Rationalt& rhs); const RaT& operator=(const RaT& rhs); // const Rationalt& operator*(const Rationalt& rhs); inline const T numerator()const { return *m_Numerator;} inline const T denominator()const{ return *m_Denominator;} void reviseNumerator(T val); void reviseDenominator(T val); inline ~Rationalt(){ this->m_Numerator = nullptr;//置为nullpr! this->m_Denominator = nullptr;//置为nullpr! } private: std::shared_ptr<T> m_Numerator; std::shared_ptr<T> m_Denominator; }; template<typename T> Rationalt<T>::Rationalt(const Rationalt<T>& rhs){ this->m_Numerator.reset(); m_Numerator = make_shared<T>(rhs.numerator()); this->m_Denominator.reset(); m_Denominator = make_shared<T>(rhs.denominator()); } template<typename T> const Rationalt<T>& Rationalt<T>::operator=(const Rationalt<T>& rhs){ this->m_Numerator.reset(); m_Numerator = make_shared<T>(rhs.numerator()); this->m_Denominator.reset(); m_Denominator = make_shared<T>(rhs.denominator()); return *this; } template<typename T> // const Rationalt& operator*(const Rationalt& rhs); void Rationalt<T>::reviseNumerator(T val){ this->m_Numerator.reset(); m_Numerator = make_shared<T>(val); } template<typename T> void Rationalt<T>::reviseDenominator(T val){ this->m_Denominator.reset(); m_Denominator = make_shared<T>(val); } #endif //__RATIONALT_H__
domultiply.h:
#ifndef __DOMULTIPLY_H__ #define __DOMULTIPLY_H__ #include"rationalt.h" template<typename T> class Rationalt;//不用写为class Rationalt<T>;这样写反而会报错!!! template<typename T> const Rationalt<T> doMultiply(const Rationalt<T>& rhs1, const Rationalt<T>& rhs2){ return Rationalt<T>(rhs1.numerator() * rhs2.numerator(), rhs1.denominator() * rhs2.denominator()); } #endif //__DOMULTIPLY_H__
运行结果:(显示正常)
Error_demo1_codes:
#ifndef __DOMULTIPLY_H__ #define __DOMULTIPLY_H__ #include"rationalt.h" template<typename T> const Rationalt<T> doMultiply(const Rationalt<T>& rhs1, const Rationalt<T>& rhs2){ return Rationalt<T>(rhs1.numerator() * rhs2.numerator(), rhs1.denominator() * rhs2.denominator()); } #endif //__DOMULTIPLY_H__
不加这2句话的运行结果:
Error_demo2_codes:
#ifndef __DOMULTIPLY_H__ #define __DOMULTIPLY_H__ #include"rationalt.h" template<typename T> class Rationalt<T>;//不用写为class Rationalt<T>;这样写反而会报错!!! template<typename T> const Rationalt<T> doMultiply(const Rationalt<T>& rhs1, const Rationalt<T>& rhs2){ return Rationalt<T>(rhs1.numerator() * rhs2.numerator(), rhs1.denominator() * rhs2.denominator()); } #endif //__DOMULTIPLY_H__
加这2句话但是还加上模板参数T的运行结果: