建设久久建筑网站,网站 多语,无锡装饰网站建设排名,久久建筑网怎么赚金币文章目录C模板#xff08;一#xff09;1. 泛型编程2. 函数模板2.1 函数模板格式2.2 模板原理2.3 模板实例化2.4 模板参数匹配原则3. 类模板3.1 类模板格式3.2 背景3.3 类模板的实例化C模板#xff08;一#xff09;
1. 泛型编程
前面我们学到了函数重载这个特性#xf…
文章目录C模板一1. 泛型编程2. 函数模板2.1 函数模板格式2.2 模板原理2.3 模板实例化2.4 模板参数匹配原则3. 类模板3.1 类模板格式3.2 背景3.3 类模板的实例化C模板一
1. 泛型编程
前面我们学到了函数重载这个特性对于交换函数可能要写int和int类型的交换可能要写double和double类型的交换还可能写char和char类型的交换这样就有不好之处
函数重载仅仅是类型不同代码复用率低只要新类型出现时就需要重构代码可维护性低
那么能否告诉编译器一个模板让编译器根据不同类型利用该模板来生成代码呢那么这里就需要用到C模板。
泛型编程就是编写与类型无关的通用代码是代码复用的一种手段。
2. 函数模板
2.1 函数模板格式 templatetypename T1, typename T2, … , typename Tn templateclass T
void Swap(T x, T y)
{T tmp x;x y;y tmp;
}typename是用来定义模板参数的关键字也可以用class。
2.2 模板原理
函数模板就是一个蓝图本身并不是函数是编译器用来产生特定具体类型函数的模具而已把重复的事交给了编译器做。 编译器编译阶段编译器需要根据传入的实参类型来推演出对应的类型函数以供调用
2.3 模板实例化 用不同类型的参数使用函数模板时称为函数模板的实例化。模板参数实例化分为隐式实例化和显式实例化 templateclass T
T Add(const T e1, const T e2) //隐式实例化让编译器根据实参推演参数的实际类型
{return e1 e2;
}int main()
{int a1 10, a2 20;double d1 10.1, d2 20.1;cout Add(a1, a2) endl; //两个实参类型都是intcout Add(d1, d2) endl; //两个实参类型都是double//cout Add(a1, d1) endl; //error,一个实参是int一个实参是double//怎么来解决这里的错误呢//1.手动强制转化cout Add(a1, (int)d1) endl;cout Add((double)a1, d1) endl;//2.使用显示实例化显示实例化在函数名后的中指定模板参数的实际类型cout Addint(a1, d1) endl;cout Adddouble(a1, d1) endl;//3.增加一个模板参数//templateclass T -- templateclass T1, class T2return 0;
}2.4 模板参数匹配原则
一个非模板函数可以和一个同名的函数模板同时存在而且该函数模板还可以被实例化为这个非模板函数
int Add(int left, int right)
{return left right;
}templateclass T
T Add(T left, T right)
{return left right;
}
void Test()
{Add(1, 2); // 调用非模板Addint(1, 2); // 调用模板
}对于非模板函数和同名函数模板如果其他条件都相同在调动时会优先调用非模板函数而不会从该模板产生出一个实例。如果模板可以产生一个具有更好匹配的函数 那么将选择模板
int Add(int left, int right)
{return left right;
}
templateclass T1, class T2
T1 Add(T1 left, T2 right)
{return left right;
}
void Test()
{Add(1, 2); // 与非函数模板类型完全匹配不需要函数模板实例化Add(1, 2.0); // 模板函数可以生成更加匹配的版本编译器根据实参生成更加匹配的Add函数
}模板函数不允许自动类型转换但普通函数可以进行自动类型转换
3. 类模板
3.1 类模板格式
templateclass T1, class T2, ..., class Tn
class 类模板名
{// 类内成员定义
};3.2 背景
//栈
typedef int stackType;
class stack
{
private:int* _a;int _top;int _capacity;
};int main()
{stack s1;stack s2;//一个typedef可以让s1这个栈存放int类型的s2这个栈存放double类型的吗 不能所以就要用到类模板return 0;
}改进
templateclass T
class stack
{
private:T* _a;int _top;int _capacity;
};int main()
{stackint s1; //类模板只能显示实例化stackdouble s2;return 0;
}注意类模板中函数放在类外进行定义时需要加模板参数列表
templateclass T
class stack
{
public:stack(int capacity 4){_a new T[capacity];_top -1;_capacity capacity;}~stack();
private:T* _a;int _top;int _capacity;
};templateclass T
stackT::~stack() //类模板中函数放在类外进行定义时需要加模板参数列表
{if (stack::_a ! nullptr) {delete[] _a;_top -1;_capacity 0;}
}3.3 类模板的实例化
类模板实例化与函数模板实例化不同类模板实例化必需要在类模板名字后跟然后将实例化的类型放在中即可类模板名字不是真正的类而实例化的结果才是真正的类另外vector int v中vector是类名vector int 才是对象v的类型。