-
-
class的特点:
-
显示接口
-
运行期多态
-
-
template的特点:
-
隐式接口
-
编译器多态,模板的具现和函数的重载
-
-
使用typename关键字声明嵌套从属类型名称,但不可以出现在基类列表和初始化里列表中
-
嵌套从属名称
template<typename C> void Print2Nd(const C& container) { ... typename C::const_iterator iter(container.begin()) //确认是类型不是名称 ... } //C::const_iterato 从属嵌套类型(名称中依赖于template类型参数)
-
-
this->xxx (建议)
-
basename::xxx
-
using basename::xxx
-
class CompanyA{ public: CompanyA(){} void Send() { cout<<"CompanyA::Send()"<<endl; } }; class CompanyB{ public: CompanyB(){} void Send() { cout<<"CompanyB::Send()"<<endl; } }; template<typename Company> class Sender{ public: Sender(){} void SendMsg() { Company c; c.Send(); } }; template<typename Company> class LogSender: public Sender<Company> { public: using Sender<Company>::SendMsg; void LogSendMsg() { cout<<"LogSender::LogSendMsg() before"<<endl; SendMsg(); //单独使用错误,配合using使用ok this->SendMsg(); //OK Sender<Company>::SendMsg(); //OK cout<<"LogSender::LogSendMsg() after"<<endl; } };
-
不要将函数参数提取为template,这样导致代码冗余
运用成员函数模板接受所有兼容类型
-
使用模板成员函数生成可接受和兼容所有类型的函数,包括构造函数
template<typename U> class A { public: template<typename T> A(A<T>& other) { ... } };
-
如果将构造函数声明为模板函数,为了阻止编译器生成默认的构造函数,你必须明确声明一个非模板的构造函数
-
template在推倒虑隐式转换
-
对比“定义no-member函数进行类型转换”这一条规则
template<typename T> const Rational<T> doMutliply(const Rational<T>& lhs, const Rational<T>& rhs) { ... } template<typename T> class Rational { public: ... //声明为friend函数的目的是tempalte推倒,保证编译通过,根本目的是提供一个使用是所有类型的乘法 frined const Rational<T>operator*(const Rational<T>& lhs, const Rational<T>& rhs) { return doMutliply(lhs, rhs); } }
-
需要了解STL编程,可以参考《STL源码剖析》一书
-
运用到模板、元编程等知识
-
元编程将运行期的工程提前到编译期,错误的发现更早,效率更高