当前位置:首页 » 《随便一记》 » 正文

还在因为写项目函数太多而烦恼?C++模板一文带你解决难题

18 人参与  2023年05月02日 16:25  分类 : 《随便一记》  评论

点击全文阅读


在这里插入图片描述

?作者介绍:22级树莓人(计算机专业),热爱编程<目前在c++阶段>——目标Windows,MySQL,Qt,数据结构与算法,Linux,多线程,会持续分享学习成果和小项目的
?作者主页:热爱编程的小K
?专栏链接:c++

?欢迎各位→点赞? + 收藏? + 留言?​
?总结:希望你看完之后,能对你有所帮助,不足请指正!共同学习交流 ?

在这里插入图片描述

?文章目录

?一、什么是模板?二、C++函数模板?三、函数模板操作自定义类型?四、C++类模板?五、稍微复杂一点的类模板


?一、什么是模板

模板是一种忽略数据的一种泛型编程。把数据当做未知量,当使用的时候传入类型的一种编程方式

语法

template <class T>//告诉编译器,接下来要用到一个未知类型是T类型
template <typename T>//等效class
template <class T1,class T2,class T3> //三个未知类型

#include<iostream>#include<string>using namespace std;#if 0int Max(int a, int b) {return a > b ? a : b;}float Max(float a, float b) {return a > b ? a : b;}double Max(double a, double b){return a > b ? a : b;}#endiftemplate <class T1> T1 Max(T1 a,T1 b){return a > b ? a : b;}int main() {cout << Max<int>(9, 10);return 0;}

?二、C++函数模板

函数模板调用 函数模板隐式调用显示调用:函数名<未知类型>(函数参数) 函数模板本质就是函数传参 函数模板也是可以缺省 函数模板中存在变量 这种函数模板必须显示调用变量传参只能传入常量 当函数模板和普通函数相遇 优先调用类型一致的普通函数显示调用一定调用模板 函数模板重载 优先调用传参数目少的函数模板
#include<iostream>#include<string>using namespace std;template <class T1> T1 Max(T1 a, T1 b) {return a > b ? a : b;}template <class _T1, class _T2, class _T3> void print(_T1 a, _T2 b, _T3 c) {cout << a << "\t" << b << "\t" << c << endl;}template <class _T1 = int, class _T2 = string, class _T3 = double> void printData(_T1 a, _T2 b, _T3 c){cout << a << endl << b << endl << c << endl;}template <class _T1,int size> _T1* createNew(){_T1* createNew = new _T1[size];return createNew;}template <class _T1, int size=5> _T1* createParry(){_T1* createNew = new _T1[size];return createNew;}template <class _Ty, int size = 4> void printArray2(_Ty array[]){for (int i = 0; i < size; i++){cout << array[i] << "\t";}cout << endl;}void Func1(int a, double b, string c) {cout << "普通函数" << endl;}template <class _T1, class _T2, class _T3> void Func1(_T1 a,_T2 b,_T3 c) { cout << "三个" << endl; }template <class _T1, class _T2> void Func1(_T1 a, _T2 b, _T2 c) { cout << "两个" << endl; }template <class _T1> void Func1(_T1 a,_T1 b,_T1 c) { cout << "一个" << endl; }void test1() {//函数模板存在变量,必须显示调用int* parry = createNew<int, 5>();//变量缺省时候可以隐式调用double* king = createParry<double>();int p[4] = { 1,2,3,4 };printArray2(p);}void test2(){//函数模板重载,普通函数Func1<int, double, string>(1,1.11,string("king"));Func1(1, 1.11,string("king"));Func1(1, string("asdd"),string("kkk"));Func1(1, 1, 1);}int main(){//隐式调用cout << Max(1, 2) << endl;cout << Max(1.1, 1.2) << endl;cout << Max(string("abc"), string("abd")) << endl;print(123, string("king"), 1.55);//显示调用cout << Max<int>(1, 2) << endl;cout << Max<string>(string("abc"), string("abd")) << endl;print<string, int, double>("asdas", 123, 123.213);//函数模板的缺省printData(1, "dad", 1.11);printData<double, int, string>(1.11, 1, "dasdf");test1();test2();return 0;}

?三、函数模板操作自定义类型

操作自定义类型的关键点就是重载

#include<iostream>#include<string>using namespace std;template <class _T1> void printpArry(_T1 arry[],int arryNums){for (int i = 0; i < arryNums; i++){cout << arry[i] << endl;}cout << endl;}template <class _T1> void Sort(_T1 arry[], int arryNums) {for (int i = 0; i < arryNums; i++){for (int j = 0; j < arryNums - i - 1; j++) {if (arry[j] > arry[j + 1]) {_T1 temp = arry[j];arry[j] = arry[j + 1];arry[j + 1] = temp;}}}}class MM {public:MM(string name="", int age=0):name(name),age(age){}friend ostream& operator<<(ostream& out,const MM& object){out << object.age << "\t" << object.name << endl;return out;}bool operator>(const MM& object) {return this->name > object.name;}string Getname() const { return this->name; }int Getage() const { return this->age; }protected:string name;int age;};template <class _T1> void Sort2(_T1 arry[], int arryNums,bool(*compare)(const _T1& one,const _T1& two)){for (int i = 0; i < arryNums; i++){for (int j = 0; j < arryNums - i - 1; j++){if (compare(arry[j] , arry[j + 1])){_T1 temp = arry[j];arry[j] = arry[j + 1];arry[j + 1] = temp;}}}}bool compareByname(const MM& one, const MM& two){return one.Getname() > two.Getname();}bool compareByage(const MM& one, const MM& two){return one.Getage() > two.Getage();}int main() {int parry[5] = { 1,20,6,7,90 };Sort(parry, 5);printpArry(parry, 5);MM mm[3];mm[0] = { "e",123 };mm[1] = { "b",241 };mm[2] = { "d",345 };Sort(mm, 3);printpArry(mm, 3);Sort2(mm, 3,compareByage);printpArry(mm, 3);return 0;}

?四、C++类模板

template修饰的类就是类模板模板类必须显示实例化,简单来说必须要传参模板类不是一个真正的类型 声明和实现必须写在一起,所谓一起就是同一个文件中所有用到类型的地方必须要用类名<未知类型>的用法 类模板特化 局部特化:特殊化处理,例如两个未知变成一个未知类型完全特化:具体化类型
#include<iostream>#include<string>using namespace std;template <class _T1,class _T2> class Data{public:void print();static int count;};template <class _T1, class _T2> int Data<_T1, _T2>::count = 0;template <class _T1, class _T2> void Data<_T1, _T2>::print() {cout << "类中模板函数" << endl;}//类模板的继承template <class _T1, class _T2> class Son : public Data<_T1, _T2> {public:protected:};struct MMinfor {string name;int age;};ostream& operator<<(ostream& out, const MMinfor& object) {out << object.age << "\t" << object.name << endl;return out;}struct MMscore {int math;int english;int chinese;};ostream& operator<<(ostream& out, const MMscore& object){out << object.math << "\t" << object.english << "\t" << object.chinese << endl;return out;}template <class _T1, class _T2> class MM {public:MM(_T1 one,_T2 two):one(one),two(two){}void print() { cout << one << "\t" << two << endl; }protected:_T1 one;_T2 two;};void test1(){MM < string, int > mm("king", 19);mm.print();MM<int, int> complaxe(1, 1);complaxe.print();//MMinfor info{string("zhang"), 18};//MMscore score{ 13,14,123 };//MM<MMinfor, MMscore> king(info, score);MM<MMinfor, MMscore> king({ "zhang",18 }, { 31,312,453 });king.print();}//类模板特化template <class _T1, class _T2, class _T3> class A{public:A(_T1 one,_T2 two,_T3 three):one(one),two(two),three(three){cout << "三个类型" << endl;}protected:_T1 one;_T2 two;_T3 three;};//局部特化template <class _T1> class A<_T1,_T1,_T1>{public:A(_T1 one, _T1 two, _T1 three) :one(one), two(two), three(three){cout << "局部特化" << endl;}protected:_T1 one;_T1 two;_T1 three;};//完全特化template <> class A<int,int,int>{public:A(int one, int two, int three) :one(one), two(two), three(three){cout << "完全特化" << endl;}protected:int one;int two;int three;};void Test() {A<int, int, int> a(1, 2, 3);A<int, string, double> b(1, "as", 1.22);A<int, int, double> c(1, 2, 1.22);//三个类型A<string, string, string> d("qew", "fasd", "fads");}int main(){Data<int, string> data;Data<string, int>* object = new Data<string, int>;data.print();object->print();//两个不同类型中的count,不会因为一个类型中值的改变而另一个类型中的值改变cout << Data<int, string>::count << endl;cout << Data<string, string>::count << endl;test1();Test();return 0;}

?五、稍微复杂一点的类模板

稍微复杂一点的模板就是模板类与模板类的嵌套,本质不难,大家学会剥洋葱,学会用别名替换即可

#include<iostream>#include<string>using namespace std;template <class _T1, class _T2> class MM {public:MM(_T1 one, _T2 two) :one(one), two(two) {}void print() { cout << one << "\t" << two << endl; }template <class _T1, class _T2> friend ostream& operator<<(ostream& out,const MM<_T1, _T2>& object);protected:_T1 one;_T2 two;};template <class _T1, class _T2> ostream& operator<<(ostream& out,const MM<_T1, _T2>& object){out << object.one << "\t" << object.two << endl;return out;}template <class _T1, class _T2> class Data {public:Data(_T1 one,_T2 two):one(one),two(two){}void print() { cout << one << "\t" << two << endl; }template <class _T1, class _T2>friend ostream& operator<<(ostream& out, const Data<_T1, _T2>& object);protected:_T1 one;_T2 two;};template <class _T1, class _T2> ostream& operator<<(ostream& out, const Data<_T1, _T2>& object){out << object.one << "\t" << object.two << endl;return out;}int main() {MM<int, string> info(19, "king");MM<int, int> score(99, 88);Data< MM<int, string>, MM<int, int>> king(info, score);king.print();using kk = Data< MM<int, string>, MM<int, int>>;using kkk = MM<int, string>;Data<kk, kkk> data(king, info);data.print();return 0;}

点击全文阅读


本文链接:http://m.zhangshiyu.com/post/60232.html

<< 上一篇 下一篇 >>

  • 评论(0)
  • 赞助本站

◎欢迎参与讨论,请在这里发表您的看法、交流您的观点。

关于我们 | 我要投稿 | 免责申明

Copyright © 2020-2022 ZhangShiYu.com Rights Reserved.豫ICP备2022013469号-1