民政局两学一做专题网站,莱芜网站建设价格,微信小程序和网站开发有什么区别,网站 搭建 亚洲服务器目录
前言#xff1a;
1.泛型编程
2.函数模版
3.类模版
为什么要有类模版#xff1f;使用typedef不行吗#xff1f;
类模版只能显示实例化#xff1a;
注意类名与类型的区别#xff1a;
注意类模版最好不要声明和定义分离#xff1a;
总结#xff1a; 前言
1.泛型编程
2.函数模版
3.类模版
为什么要有类模版使用typedef不行吗
类模版只能显示实例化
注意类名与类型的区别
注意类模版最好不要声明和定义分离
总结 前言
正如标题而言这里只是对模版的简单认识与使用方便后面博客介绍stl中一些容器的实现更复杂详细的模版相关的内容将会在模版进阶中介绍。
1.泛型编程
编写与类型无关的通用代码是代码复用的一种手段模版是泛型编程的基础。
而模版又分为函数模版与类模版。 2.函数模版
templateclass T
void Swap(T x, T y)
{T tmp x;x y;y tmp;
}int main()
{int a 1, b 2;double c 1.0, d 2.0;Swap(a, b);Swap(c, d);return 0;
}
首先要注意第一点
两次调用的Swap函数实际都不是同一个函数第一是函数调用开辟的栈帧都不一样大一个是int一个是double第二是汇编call的函数的地址也是不一样的。
这里的class可用typename替换区别在后面的学习中会介绍。 补充一下库中的swap函数 那模版参数是怎么识别不同的类型的呢这就是模版的实例化实际就是编译器帮你完成了这个工作是隐式的实例化自动推演模版的类型。模版的实例化发生在编译时期所以是在编译的时候根据类型推导生成的代码 那下面来看两个问题首先第一个传的模版参数不明确会报错
templateclass T
T Add(const T left, const T right)
{return left right;
}int main()
{int a 1;double b 1.1;Add(a, b);//报错解决方法1
强制转换类型但是会丢失精度。
Add(a1,(int)d1); 解决方法2
使用显示实例化其实经历了隐式类型转换
coutAddint(a,b)endl;//实际b转int经过了隐式类型转换 问题2这样的能同时存在吗
int Add(int left, int right)
{return left right;
}templateclass T
T Add(const T left, const T right)
{return left right;
}templateclass T1,class T2
T1 Add(T1 left, T2 right)
{return left right;
}int main()
{int a 1;double b 1.1;Add(a, b);
}首先前两个能同时存在吗答案是可以的因为函数名的修饰规则可能不一样。
其次调用的时候都传的类型是int类型前两个应该谁先调用呢答案是会调用第一个因为第一个在编译是就确定了地址直接就调用了而第二个在编译时才根据类型推导生成对应的代码也就是先要经历模版的实例化。
那如何就想调用模版呢使用模版的显示实例化呗Addint(a,b);
那在这3个模版中传的类型不一样会先去调用哪一个答案是去调用第三个编译器是聪明的会去调用最合适最匹配的那一个而如果没有第三个对应的才会调用第二个。 3.类模版
格式就是:
templateclass T1,class T2,...,class Tn
class 类模版名
{//类成员定义
};为什么要有类模版使用typedef不行吗 如果我们使用typedef那第一类想要int第二个类想要double是不是还要再写两个类所以就用到了类模版但是还是调用了两个类编译器帮你实现了 注意类里面的构造函数new了需要析构时delete因为类的对象销毁会调用析构。 类模版只能显示实例化
因为就算调用构造函数也传不到T的身上啊并且传的值要怎么识别是T呢 注意类名与类型的区别 vectorint v1;不加上模版参数只是类名加上才是类型。 注意类模版最好不要声明和定义分离
这里指的是头文件放类模版的定义.cpp文件放声明分文件的声明定义分离否则会出现链接错误虽然有解决方式但是还是不建议至于为什么到模版进阶会介绍。 如果想要类模版的声明和定义分离目前可以放到在同一个文件里面然后可以在类里面声明在类外面定义拿析构函数举例注意类模版的定义要写在这个类的下面不然找不到。但是还是不建议分开写容易出错
class Vector
{
public:Vector(int capacity4){_pDate new T[capacity];_size _capacity 0;}~Vector();private:T* _pDate;int _size;int _capacity;
};templateclass T
VectorT::~Vector()
{delete[] _pDate;_pDate nullptr;_size _capacity 0;
}int main()
{Vectorint v1;return 0;
} 总结
本篇偏重基本的使用和注意事项关于模版更进阶的到模版进阶篇再介绍。