模板的继承关系其实与普通的继承区别不大,但在模板继承的关系中,有一些特殊的继承关系。奇异的递归继承模板模式(CRTP)不是一种新技术,而是一种模板编程时使用的编程手法----把派生类作为基类的模板参数。
代码示例:
template <typename T> //T代表着派生类
class Base //Base是类模板
{
public:
void asDerived()
{
T& derived = static_cast<T&>(*this);
derived.myfunc(); //调用派生类的成员函数
}
private:
Base() {};
friend T;
};
class Derived1 : public Base<Derived1> //Derived1是普通类
{
public:
void myfunc()
{
cout << "Derived1::myfunc()执行了" << endl;
}
//......
};
int main()
{
_nmsp1::Derived1 myd;
myd.asDerived(); //调用基类的成员函数
}
输出:Derived1::myfunc()执行了
基类调用派生类的接口与多态体现:
因为基类可以调用派生类的方法,所以,有很多事可以在基类中做。看下面这个范例:
//基类模板
template <typename T>
class Human
{
public:
const T& toChild() const
{
return static_cast<const T&>(*this);
}
T& toChild()
{
return static_cast<T&>(*this);
}
void parenteat()
{
toChild().eat();
}
private:
Human() {};
friend T;
};
class Men : public Human<Men>
{
public:
void eat()
{
cout << "男人喜欢吃面食!" << endl;
}
};
class Women : public Human<Women>
{
public:
void eat()
{
cout << "女人喜欢吃米饭!" << endl;
}
};
template<typename T>
void myHumanFuncTest(Human<T>& tmpobj)
{
tmpobj.parenteat();
}
_nmsp2::Men mymen;
_nmsp2::Women mywomen;
mymen.parenteat();
mywomen.parenteat();
cout << "-----------------------" << endl;
myHumanFuncTest(mymen);
myHumanFuncTest(mywomen);
从上面的这个例子中可以看到,在基类增加方法,派生类对象都能调用,另外通过myHumanFuncTest()调用的观察,这里也涉及了静态多态(在编译期间就确定具体调用谁)的概念,从此例中,如果不用奇异的递归模板模式,而是把eat()成员函数在基类和派生类中都写成虚函数,也可以实现多态的功能,但是如果eat()是一个函数模板或静态成员函数,那么就没有办法将其实现为一个虚函数了,此时就有必要采用奇异的递归模板模式实现虚函数的多态效果了
919

被折叠的 条评论
为什么被折叠?



