C++类模板继承关系

编程入门 行业动态 更新时间:2024-10-23 08:31:35

C++类<a href=https://www.elefans.com/category/jswz/34/1770549.html style=模板继承关系"/>

C++类模板继承关系

一共有这三种关系:

一、类模板从类模板派生

首先明确一点,子类肯定是要实例化的。子类实例化的时候要调用父类的构造函数,所以父类也是要实例化的。所以子类实例化的时候必须也要将父类实例化,所以子类模板的参数也必须支持对于父类的实例化。
看代码:

实例(1)

父类模板的实例化规则完全由子类掌握。

template<typename T1, typename T2>
class Base
{T1 t1;T2 t2;
public:Base(T1 a, T2 b):t1(a),t2(b){}void display(){cout<<t1<<" "<<t2<<endl;}
};template<typename T1,typename T2>
class Derived: public Base<T2,T1>
{T1 t1;T2 t2;
public:Derived(T1 a, T2 b): Base<T2, T1>(b,a),t1(a),t2(b){}void display(){Base<T2,T1>::display();cout<<endl;cout<<t1<<" "<<t2<<endl;}
};int main(){Derived<int,string> d(1,"123");d.display();
}

输出结果:

123 11 123

当Derived实例化之后,Base也会连带实例化。

template<typename T1,typename T2>
class Derived: public Base<T2,T1>

继承的时候,子类控制父类如何实例化。

实例(2)

父类模板继承的时候部分实例化。

template<typename T1, typename T2>
class Base
{T1 t1;T2 t2;
public:Base(T1 a, T2 b):t1(a),t2(b){}void display(){cout<<t1<<" "<<t2<<endl;}
};template<typename T1,typename T2>
class Derived: public Base<T1,char>
{T1 t1;T2 t2;
public:Derived(T1 a, T2 b): Base<T1,char>(a,'b'),t1(a),t2(b){}void display(){Base<T1,char>::display();cout<<endl;cout<<t1<<" "<<t2<<endl;}
};int main(){Derived<int,string> d(1,"123");d.display();
}

输出:

1 b1 123

当然,继承的时候也可以控制父类模板部分实例化,但是注意一点。部分实例化后,父类模板仍然是模板。

实例(3)

父类模板完全实例化

template<typename T1, typename T2>
class Base
{T1 t1;T2 t2;
public:Base(T1 a, T2 b):t1(a),t2(b){}void display(){cout<<t1<<" "<<t2<<endl;}
};template<typename T1,typename T2>
class Derived: public Base<int,string>
{T1 t1;T2 t2;
public:Derived(T1 a, T2 b): Base(a,b),t1(a),t2(b){}void display(){Base::display();cout<<endl;cout<<t1<<" "<<t2<<endl;}
};int main(){Derived<int,string> d(1,"123");d.display();
}

输出结果:

1 1231 123

这种情况,完全可以将父类模板看作一个普普通通的类,因为已经彻底实例化了。
我们可以看到一个有意思是事情,只有彻底实例化的模板,在调用构造函数和display()的时候不需要指定模板实例化类型,原因我会在后续的博文里面解释。

二、类模板从普通类派生

class Base
{int t1;int t2;
public:Base(int a, int b):t1(a),t2(b){}void display(){cout<<t1<<" "<<t2<<endl;}
};template<typename T1,typename T2>
class Derived: public Base
{T1 t1;T2 t2;
public:Derived(T1 a, T2 b): Base(123,456),t1(a),t2(b){}void display(){Base::display();cout<<endl;cout<<t1<<" "<<t2<<endl;}
};int main(){Derived<int,string> d(1,"123");d.display();
}

这个可能是最常用的用法了。大家只需要牢牢记住一点:子类模板实例化的时候,其行为与结构是否合理。
其实,这个完全等价于上一小节的实例(3)。

三、普通类从模板类派生

不说那些虚的了,记住一句话:
普通类不能继承于模板类!!!
模板类如果想被普通类继承,那么必须要实例化!!!

四、总结

上面的种种现象,只需要记住一下几个点,全部都可以解释通:
(1)子类构造对象的时候,必然要给父类构造对象;
(2)构造对象的前提是明确类型,没有实例化的模板是不能构造对象的。
(3)子类确定类型的时候,如果父类的类型不明确,那么就无法构造对象。

更多推荐

C++类模板继承关系

本文发布于:2023-11-15 15:53:52,感谢您对本站的认可!
本文链接:https://www.elefans.com/category/jswz/34/1602312.html
版权声明:本站内容均来自互联网,仅供演示用,请勿用于商业和其他非法用途。如果侵犯了您的权益请与我们联系,我们将在24小时内删除。
本文标签:模板   关系

发布评论

评论列表 (有 0 条评论)
草根站长

>www.elefans.com

编程频道|电子爱好者 - 技术资讯及电子产品介绍!