|
一、函数模板的引出: 1、c++中有几种交换变量的方法: (1)定义宏代码块 (2)定义函数 代码版本一: #include <iostream>#include <string>3 n8 l1 x5 X' Q1 b4 X) } using namespace std;6 f+ X, q' b/ d& {& D% n9 g+ v #define SWAP(t,a,b) \3 X$ F- b2 P4 N3 {' q do \ { \ t c =a; \3 {4 H+ q8 S/ K& p; s a =b; \ b = c; \ }while(0) & v: ]+ R) r% I9 ^4 @4 a$ y int main()$ ?1 ] H1 M1 k { int a =2; int b =5; ' q/ w, j) @% W1 Q: z% N! q/ T% ?7 k SWAP(int , a , b );; { Y: V9 k- i7 d/ U2 h0 R4 L9 {% N cout<<"a= "<<a<<endl;% `$ `! L" w6 g3 _9 ?2 O$ M8 \: {# |: B cout<<"b= "<<b<<endl; double m =4;6 A6 d) \: D, M" z$ m7 c' i double n =6; cout<<"m = "<<m<<endl; cout<<"n= "<<n<<endl; return 0;8 ~( a% p; D5 \# _( G } 输出结果: root@txp-virtual-machine:/home/txp# ./a.outa= 51 b& l2 z) r" o! \; a; `8 ? b= 26 X+ ^. s# g: {8 @ m = 4- |2 S* L9 {& l8 N& |, ` n= 6 ! g# D- F- F1 }# m 注解:我们看两个数值交换成功。 我们再用使用函数的方式来实现这个功能,当然以前我们在c语言里面使用指针传参方式来实现这种两个数值直接的交换,现在我们利用c++里面更加高级的方式来实现,就是使用引用来实现(不过它的本质还是指针来实现,只是我们只用引用再不用去考虑指针的细节了) 代码版本二: #include <iostream>( p! Q- h) ^: {7 \0 x#include <string> using namespace std;/ \9 `" x3 \' u/ f/ \: a / H1 {6 M# ?- q b* K& `2 t1 x void Swap(int& a , int& b )//const int * a ,const int * b ' { int c =a; a=b; b=c; } void Swap(double& a,double& b)+ u) ^9 T" j6 K' z/ k {& E2 y, A7 Y. ^; D double c =a; a=b; b=c; }6 b3 D/ k2 |; z4 U+ A : ]& K, R( }, T) U W void Swap( string& a, string& b) {% O# g% W, X$ Q string c =a; a=b;7 G7 s" z$ I% R4 U8 ` b=c;' ]; y3 U+ |3 V0 B6 v }) u9 \& C) b, g$ \ int main()0 q! g; c& {: ]8 D {( C& m0 z4 v6 G- G int a =2; int b =5;7 F; ^2 {4 H! Y: y+ ` " T( }$ M/ D z+ N; e9 M" P* x Swap(a,b);4 M, u5 U0 r) |1 c cout<<"a= "<<a<<endl; cout<<"b= "<<b<<endl;+ x7 N6 t1 R5 M" P# P* n3 Y Q- k s - q/ k; B0 U! Z- n. h0 T! M double m =4; double n =6;! n5 I4 I, T \8 q cout<<"m= "<<m<<endl;$ h. h2 X' [1 ]- L$ e cout<<"n= "<<n<<endl;/ I. P5 Q2 `, D6 f: N( J, d 6 |* N& Q0 j+ c$ U1 Q& O3 _ string d = "Txp"; string t = "xiaoping";3 W, a5 k! u2 ~5 U- Y ?# r+ x5 m4 G L, ^2 v cout<<"d= "<<d<<endl;! T" D0 ~8 S7 O cout<<"t= "<<t<<endl;9 M, b1 f1 Y8 } t M$ U5 | return 0;! ` Q- y; W* n2 k# [) r# k! ~ }( F6 G9 g' f/ L y2 Q8 P2 M2 w ( i7 C. R3 \% Q8 R; D 输出结果: root@txp-virtual-machine:/home/txp# ./a.outa= 5( _' E; a+ D0 I. O; f/ { b= 2! C+ B6 ^5 d/ x# s- I7 H m= 4' z2 ]0 q; Y8 X5 r# } S n= 6) u1 o" h3 ^6 }& m6 B6 K! P d= Txp t= xiaoping / L( R( Y5 k9 Z U/ B 注解:同样实现了交换功能。 2、两种方法的优缺点: 定义宏代码块 -优点:代码复用,适合所有的类型 -缺点:编译器不知道宏的存在,缺少类型检查 定义函数 -优点:真正的函数调用,编译器对类型进行检查 -缺点:根据类型重复定义函数,无法diam复用,从上面的试验结果可以看出,我们每次都对Swap()函数进行重新定义,定参数的类型不一致的时候 二、泛型编程闪亮出场: 1、泛型编程的概念: 不考虑具体数据类型的编程方式,我们可以继续拿我们刚才的那个Swap函数进行改造,改成我们现在的泛型写过: void Swap(T& a, T& b){% \' l6 [+ F2 N' J T t =a; a =b;; x" |* r1 n% S6 k b =t;. \2 k$ t; k) z. [" \) c5 }1 n }, c9 k. b, G- `% m9 V9 Q6 R# r 注解:Swap泛型写法中的T不是一个具体的数据类型,而是泛指任意的数据类型,这一点非常重要,明显有了很大提升。 2、C++中泛型编程 (1)函数模板:
void Swap(T& a, T& b) {- }: M R3 w# `8 S) |- A% m; c T t = a;1 x9 \4 o$ k8 j% G/ d2 O a = b; b = t; }; f$ F+ W; D1 y* A9 ] (2)函数模板的语法规则:
(3)函数模板的使用
int b =1; s" ^0 [# [, ?9 @3 Z Swap(a,b)//这里属于自动推导 float c =2;, C' z( k! {: ` float d =6;( F9 H- \4 x& ?+ b, U1 ^$ H + [3 }9 f# f4 M7 o/ h6 v Swap<float>(c,d);//这里属于显示调用 代码实践: #include <iostream>#include <string>$ [! t( s( v3 y7 {' V( W9 V using namespace std; template < typename T >// 开始泛型编程,泛指类型是 T;在下面函数定义中用 T 可以代表类型; void Swap(T& a, T& b); W3 L q5 K7 p+ \" ^ {. ~: q$ ^6 {) i% B) c1 a9 W" g T c =a; a=b;9 o7 A% O4 ?% ~6 ?, ^& T' | b=c;- T9 U9 W8 L4 Q; W7 H) J6 l! x } ! K+ x5 |6 ]! P! ?6 N/ P0 R template < typename T > void Sort(T a[], int len)9 h7 w6 [( Q+ t! j p# l { for(int i=0;i<len;i++) {+ [4 w2 G5 |) x( p6 o1 U6 F* j5 T for(int j=i;j<len;j++)& x; E6 G$ u5 e/ a) A9 C {, P4 {3 R8 S+ ^( d1 H if(a > a[j]) {5 B8 U4 t) n+ ?0 p Swap(a,a[j]); }" C) z! e' e; o1 O$ `/ q }! H2 Q z8 z T$ K } # h3 [) y# ?$ r6 E) J9 T8 C5 Z }( ]* V( Z3 ^3 D) ?+ Y* y + u6 r' T( u# k" S' d i7 v . m. N% P ]3 k3 ]. k \; _ template < typename T > void Println(T a[], int len): U* ^" v+ Q4 @3 \7 B( b {- g$ }# z( M6 v/ I4 i for(int i=0;i<len;i++)7 D; e$ G* J4 v; O0 v {8 Z0 s, W" D, N8 E$ Y. D }2 B cout<<a<<",";1 o! Q; o7 ?% A7 ~ }& V9 U0 k- K& v5 H cout<<endl;" A. k; g2 z5 w }* ]7 D) L& z$ `+ j9 G& n/ l * S. c2 P! D. j2 H5 V/ y8 k int main()- H$ z$ S; A( d9 a, G! L" d; [: N {/ U# Q5 Q! i' e a7 D1 G1 J% S int a=3; int b=5;1 D: r, H s' r5 u. Z r Swap(a,b);//自动推导,等价于 Swap<int>(a, b); cout<<"a= "<<a<<endl;0 J, a1 K$ s( X3 } cout<<"b= "<<b<<endl; double m =4; double n=6;! N$ X9 q/ E8 K; q- e9 u 3 u* S9 f, A9 U o2 p Swap(m,n); cout<<"m= "<<m<<endl; cout<<"n= "<<n<<endl;" r( M. ^1 E8 J3 `$ ]! i 5 ?& V% c W: o* O* e , q) K7 k8 F: y: L8 j0 e6 q& c string d = "Txp"; string t ="xiaoping"; Swap<string>(d,t);//显示指定;将 T 替换成 string,然后进行调用; cout<<"d= "<<d<<endl;+ o: A2 D2 v+ c$ X* }$ W cout<<"t= "<<t<<endl; /* 以下是选择排序算法测试代码 */ int array[5]={3,5,6,4,9};# K" e" z- I$ @6 M. h) m. \ d* W Println(array,5); Sort(array,5); Println(array,5); string s[5]={"c","c++","rust","golang","python"}; " P! U( q% ]0 I; X. r& U9 O& C( Y Println(s,5);/ S# M: F8 }8 D1 d! L% a: ]3 b Sort(s,5);$ N$ j* t+ M% T$ Q6 I8 w8 f Println(s,5);" ]+ j8 k# M8 l' ~: W( E3 T- n 9 I# ~; \; {* L; A- {4 w0 P return 0;3 }& T1 y) M j3 b }5 M5 c8 Q2 a" u4 g$ h# Y1 d , ^1 E5 P+ H9 h3 v% T4 G+ `: _ 输出结果: vroot@txp-virtual-machine:/home/txp# ./a.outa= 5 b= 38 m2 k8 u3 I. P& R \ m= 6 n= 4+ ]- R( H, s! t F d= xiaoping* o0 S9 @; n& x- o" Z' Y/ s t= Txp 3,5,6,4,9,1 a& z3 }, U6 f2 U# ~' p 3,4,5,6,9,; K4 X- R' g& g0 ^$ G4 ]( h c,c++,rust,golang,python, c,c++,golang,python,rust,: w4 R* Q d1 p2 ?$ {& N 三、总结:
好了,今天的分享就到这里,如果文章中有错误或者不理解的地方,可以交流互动,一起进步。 |
微信公众号
手机版