C++语言基础(18)-模板
Java中的泛型编程可以极大的提升编程的效率,比如在android中查找一个控件的ID:标准写法为:
TextView tv_text = (TextView)findViewById(R.id.tv_text);
或者:
ImageView iv_img = (ImageView)findViewById(R.id.iv_img);
因为同为查询控件ID,所以上面的写法可以采用泛型编程精简为:
protected final <T extends View> T getView(int id) { return (T) findViewById(id); }
这样在下次使用的时候就可以写成这样:
TextView tv_text = getView(R.id.tv_text);
C++中也有类似的东西,不过名字变了,叫模板(template)。
一.函数模板
例:交换两个相同类型变量的值
原始写法:
//交换 int 变量的值 void Swap(int *a, int *b){ int temp = *a; *a = *b; *b = temp; } //交换 float 变量的值 void Swap(float *a, float *b){ float temp = *a; *a = *b; *b = temp; } //交换 char 变量的值 void Swap(char *a, char *b){ char temp = *a; *a = *b; *b = temp; } //交换 bool 变量的值 void Swap(bool *a, bool *b){ char temp = *a; *a = *b; *b = temp; }
使用模板后的写法:
#include <iostream> using namespace std; template<typename T> void Swap(T *a, T *b){ T temp = *a; *a = *b; *b = temp; } int main(){ //交换 int 变量的值 int n1 = 100, n2 = 200; Swap(&n1, &n2); cout<<n1<<", "<<n2<<endl; //交换 float 变量的值 float f1 = 12.5, f2 = 56.93; Swap(&f1, &f2); cout<<f1<<", "<<f2<<endl; //交换 char 变量的值 char c1 = 'A', c2 = 'B'; Swap(&c1, &c2); cout<<c1<<", "<<c2<<endl; //交换 bool 变量的值 bool b1 = false, b2 = true; Swap(&b1, &b2); cout<<b1<<", "<<b2<<endl; return 0; }
修改成引用:
#include <iostream> using namespace std; template<typename T> void Swap(T &a, T &b){ T temp = a; a = b; b = temp; } int main(){ //交换 int 变量的值 int n1 = 100, n2 = 200; Swap(n1, n2); cout<<n1<<", "<<n2<<endl; //交换 float 变量的值 float f1 = 12.5, f2 = 56.93; Swap(f1, f2); cout<<f1<<", "<<f2<<endl; //交换 char 变量的值 char c1 = 'A', c2 = 'B'; Swap(c1, c2); cout<<c1<<", "<<c2<<endl; //交换 bool 变量的值 bool b1 = false, b2 = true; Swap(b1, b2); cout<<b1<<", "<<b2<<endl; return 0; }
例:求三个数最大值:
#include <iostream> using namespace std; //声明函数模板 template<typename T> T max(T a, T b, T c); int main( ){ //求三个整数的最大值 int i1, i2, i3, i_max; cin >> i1 >> i2 >> i3; i_max = max(i1,i2,i3); cout << "i_max=" << i_max << endl; //求三个浮点数的最大值 double d1, d2, d3, d_max; cin >> d1 >> d2 >> d3; d_max = max(d1,d2,d3); cout << "d_max=" << d_max << endl; //求三个长整型数的最大值 long g1, g2, g3, g_max; cin >> g1 >> g2 >> g3; g_max = max(g1,g2,g3); cout << "g_max=" << g_max << endl; return 0; } //定义函数模板 template<typename T> //模板头,这里不能有分号 T max(T a, T b, T c){ //函数头 T max_num = a; if(b > max_num) max_num = b; if(c > max_num) max_num = c; return max_num; }
运行结果:
12 34 100
i_max=100
73.234 90.2 878.23
d_max=878.23
344 900 1000
g_max=1000
总结一下,函数模板的基本语法为:
template <typename 类型参数1 , typename 类型参数2 , ...> 返回值类型 函数名(形参列表){ //在函数体中可以使用类型参数 }
二.类模板
类模板的声明与函数模板的声明类似:
template<typename 类型参数1 , typename 类型参数2 , …> class 类名{ //TODO: };
示例代码:
#include <iostream> using namespace std; template<class T1, class T2> //这里不能有分号 class Point{ public: Point(T1 x, T2 y): m_x(x), m_y(y){ } public: T1 getX() const; //获取x坐标 void setX(T1 x); //设置x坐标 T2 getY() const; //获取y坐标 void setY(T2 y); //设置y坐标 private: T1 m_x; //x坐标 T2 m_y; //y坐标 }; template<class T1, class T2> //模板头 T1 Point<T1, T2>::getX() const /*函数头*/ { return m_x; } template<class T1, class T2> void Point<T1, T2>::setX(T1 x){ m_x = x; } template<class T1, class T2> T2 Point<T1, T2>::getY() const{ return m_y; } template<class T1, class T2> void Point<T1, T2>::setY(T2 y){ m_y = y; } int main(){ Point<int, int> p1(10, 20); cout<<"x="<<p1.getX()<<", y="<<p1.getY()<<endl; Point<int, char*> p2(10, "东京180度"); cout<<"x="<<p2.getX()<<", y="<<p2.getY()<<endl; Point<char*, char*> *p3 = new Point<char*, char*>("东京180度", "北纬210度"); cout<<"x="<<p3->getX()<<", y="<<p3->getY()<<endl; return 0; }
输出结果:
x=10, y=20
x=10, y=东京180度
x=东京180度, y=北纬210度
注意:
1.在对类模板的成员函数进行定义时,除了 template 关键字后面要指明类型参数,类名 Point 后面也要带上类型参数,只是不加 typename 关键字了
2.类模板在实例化时必须显式地指明数据类型,赋值号两边也要指明具体的数据类型,且要保持一致。
如果您觉得阅读本文对您有帮助,请点一下“推荐”按钮,您的“推荐”将是我最大的写作动力!欢迎各位转载,但是未经作者本人同意,转载文章之后必须在文章页面明显位置给出作者和原文连接,否则保留追究法律责任的权利。
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· Linux系列:如何用 C#调用 C方法造成内存泄露
· AI与.NET技术实操系列(二):开始使用ML.NET
· 记一次.NET内存居高不下排查解决与启示
· 探究高空视频全景AR技术的实现原理
· 理解Rust引用及其生命周期标识(上)
· 物流快递公司核心技术能力-地址解析分单基础技术分享
· .NET 10首个预览版发布:重大改进与新特性概览!
· 单线程的Redis速度为什么快?
· 展开说说关于C#中ORM框架的用法!
· Pantheons:用 TypeScript 打造主流大模型对话的一站式集成库