wordpress 导入工具,潍坊百度网站优化,那个网站做淘宝推广比较好,wordpress怎么添加数据库连接目录
一.范式编程
二.函数模板
1.概念与格式
2.原理
3.实例化
4.匹配规则
三.类模板 一.范式编程
在写C函数重载的时候#xff0c;可能会写很多同一类的函数#xff0c;例如交换函数#xff1a;
void Swap(int left, int right)
{int temp left;left r…目录
一.范式编程
二.函数模板
1.概念与格式
2.原理
3.实例化
4.匹配规则
三.类模板 一.范式编程
在写C函数重载的时候可能会写很多同一类的函数例如交换函数
void Swap(int left, int right)
{int temp left;left right;right temp;
}void Swap(double left, double right)
{double temp left;left right;right temp;
}void Swap(char left, char right)
{char temp left;left right;right temp;
}
针对不同的类型int,double,char...要写相似但不同的函数如上代码就存在以下问题 重载函数仅仅是类型不同但只有有新类型出现就必须增加对应的函数代码复用率比较低同时代码的可维护性也很低一个函数出错需要修改其余的重载也都需要进行修改 为了应对以上问题模版应运而生。就像活字印刷中的模板一样根据模板能够印出对应的字根据颜料的不同又能印出颜色不同的字放在C中也是同理存在模板这样一个模具在这个模具中填入不同材料类型得到不同的结果这就是范式编程。 范式编程编写与类型无关的通用代码是代码复用的一种手段模板是范式编程的基础。同时模板又有函数模板和类模板。 二.函数模板
1.概念与格式 函数模板代表了一个函数家族该函数与类型无关在使用时被参数化根据实参类型产生函数的特定类型版本。 使用的格式为 templateclass T1,class T2,...... 返回值类型 函数名参数列表{ 函数主体 } template就是使用模板的关键字class可以使用typename替代但不能使用struct替代并且class和typename可以混用可以出现templateclass T1,typename T2的情况T1,T2...代表不同的类型可以在函数的实现中使用。 具体到交换函数的函数模板就是这样
templatetypename T
void Swap(T left, T right)
{T temp left;left right;right temp;
}
可以发现T可以是int,double,char等不同类型对该模板传入不同的类型就会得到不同的特定类型函数这样就大大增加了代码复用率。
小练习 其中4,6,7是正确声明尤其注意7这样的class,typename混用是允许的。
2.原理
函数模板本质而言就是一个蓝图它本身并不是函数。就像类和对象的区别一样类是图纸对象才是实际建造起来的房子。函数模板是编译器产生特定类型具体函数的模具模板只是将本该我们做的重复事情交给了编译器。 在编译器编译阶段对于模版函数的使用编译器会根据传入的实参类型来推导生成对应的特定类型的函数也就是对于不同类型编译器会根据模板自动生成专门的函数来使用注意这里调用的函数不是同一个函数。
3.实例化
当使用不同类型的参数来使用函数模板时就被称为函数模板的实例化。函数模版的实例化分为隐式实例化和显示实例化。
隐式实例化让编译器根据实参推导模板参数的实际类型
templateclass T
T Add(const T x, const T y)
{return x y;
}int main()
{int a1 10, a2 20;double d1 10.1, d2 20.1;//a1,a2都是int类型因此编译器自动推导模板中T为int类型cout Add(a1, a2) endl;//同理此时推导T为double类型cout Add(d1, d2) endl;
} 然而也会存在编译器无法推导的情况例如此时c1和c2类型不相同c1为intc2为double那么此时编译器应该推导T为int还是double呢编译器不知道因此报出了错误。 此时可以使用多参数模板解决就是在template声明模板时再加一个类型T2,这样就能进行合适的推导了。当然也可以使用显示实例化
显示实例化直接告诉编译器这个类型T是什么此时哪怕实参不是类型T也会走隐式类型转换
例如此时若指定T为int类型那么double类型的c2就会隐式转换为20double也是同理 4.匹配规则 一个非模板函数可以和另外一个同名的函数模板同时存在而且该函数模板还可以被实例化为这个非模板函数对于非模板函数和同名函数模板如果其他条件都相同那么调用时会优先调用非模板函数从而不会实例化一个模板函数反之若模板可以实例化一个更匹配的函数那么就会选择模板 //非模板函数,适用于int类型相加
int Add(int a, int b)
{return a b;
}//函数模板适用于相加
template class T1, class T2
T1 Add(T1 a, T2 b)
{return a b;
}int main()
{Add(10, 10);//调用非模板Add(10, 10.1);//调用模板return 0;
}
注意模板函数不允许自动类型转换但普通函数是可以进行自动类型转换的。
三.类模板
类模板和函数模板类似格式为 templateclass T1, class T2 ... class 类模板名 { // 类内成员定义 }; 例如声明一个简单的Stack栈的类模板
template class T
class Stack
{
public:Stack(int capacity 4){_arr new T[capacity];_size 0;_capacity capacity;}void Push(const T data) {if (_size _capacity){int capacity_s _capacity * 2;T* tmp new T[capacity_s];memcpy(tmp, _arr, sizeof(capacity_s));_arr tmp;_capacity capacity_s;}_arr[_size] data;}private:T* _arr;int _size;int _capacity;
};int main()
{//实例化模板Stackint s1;//intStackdouble s2;//doubles1.Push(1);s1.Push(2);s2.Push(2.15);s2.Push(2.16);}
那么这跟直接实现Stack类比较有什么好处呢在直接实现的stack中通常使用typedef数据类型来使用可这也间接限制了栈储存不同类型数据的情况若同时需要一个存放int类型一个存放double类型的栈直接实现就很难了需要单独去实现两个不同类型的stack而模板就很好的解决了这一问题直接传入不同的类型来实例化针对不同数据类型的栈
// Stack是类名Stackint才是类型Stackint st1; // int类型的栈Stackdouble st2; // double类型的栈
接下来是一些类模板的练习题加深对模板的理解 下面有关C中为什么用模板类的原因描述错误的是? ( 答案C模板运行时不检查数据类型也不保证类型安全相当于类型的宏替换 下列关于模板的说法正确的是 答案D对于A而言前文在隐式类型转换时给出的Add(c1,c2)就是显然的报错编译器无法自动推导此时不能省略对于B而言类模板重点在后模板二字是未实例化的模具而模板类是根据 类模板 这个模具做出的类是类模板实例化得到的具体类对于C而言templateclass T, size_t N这样的存在是允许的虚拟类型指的是class T而size_t N并非虚拟类型 下列描述错误的是 答案D模板类是一个家族编译器的处理会分别进行两次编译其处理过程跟普通类不一样