標籤:

C++模板:函數模板、類模板、模板與繼承

http://blog.csdn.net/xiaoding133/article/details/11662183C++模板:描述

C++提供一種模板的機制來減少代碼重複。比如:對於同一樣函數使用不同的數據類型,int,double,char等。C++模板屬於「元編程」的範疇。

C++ 模板函數

1.支持不同數據類型的函數重載:

[cpp] view plaincopy

  1. #include<iostream>
  2. usingnamespacestd;
  3. intsquare(intx)
  4. {
  5. returnx*x;
  6. };
  7. floatsquare(floatx)
  8. {
  9. returnx*x;
  10. };
  11. doublesquare(doublex)
  12. {
  13. returnx*x;
  14. };
  15. main()
  16. {
  17. inti,ii;
  18. floatx,xx;
  19. doubley,yy;
  20. i=2;
  21. x=2.2;
  22. y=2.2;
  23. ii=square(i);
  24. cout<<i<<":"<<ii<<endl;
  25. xx=square(x);
  26. cout<<x<<":"<<xx<<endl;
  27. yy=square(y);
  28. cout<<y<<":"<<yy<<endl;
  29. }

2.支持所有數據類型的函數模板

[cpp] view plaincopy

  1. #include<iostream>
  2. usingnamespacestd;
  3. template<classT>
  4. inlineTsquare(Tx)
  5. {
  6. Tresult;
  7. result=x*x;
  8. returnresult;
  9. };
  10. main()
  11. {
  12. inti,ii;
  13. floatx,xx;
  14. doubley,yy;
  15. i=2;
  16. x=2.2;
  17. y=2.2;
  18. ii=square<int>(i);
  19. cout<<i<<":"<<ii<<endl;
  20. xx=square<float>(x);
  21. cout<<x<<":"<<xx<<endl;
  22. //Explicituseoftemplate
  23. yy=square<double>(y);//顯式使用模板
  24. cout<<y<<":"<<yy<<endl;
  25. yy=square(y);//隱含的方式使用模板
  26. cout<<y<<":"<<yy<<endl;
  27. }

註明:模板的關鍵字可以用class或者typename.

  • template<class T>
  • template<typename T>
  • 兩者表達的意思是一樣的,但是我更喜歡使用後者。

  • 可以採用兩種方式使用模板函數square<int>(value) or square(value).
  • 在模板函數的定義中,T代表數據類型。
  • 模板的聲明和定義必須在同一個文件中,如頭文件中。
  • C語言的宏定義也可以實現函數模板的功能,#define square(x) (x * x) 但是宏沒有類型檢查,函數模板有類型檢查。C++ 模板特例化
  • 下面的例子字元串類型需要特殊處理,採用模板的特例化

  • [cpp] view plaincopy
    1. #include<iostream>
    2. usingnamespacestd;
    3. template<classT>
    4. inlineTsquare(Tx)
    5. {
    6. Tresult;
    7. result=x*x;
    8. returnresult;
    9. };
    10. //模板特殊化
    11. template<>
    12. stringsquare<string>(stringss)
    13. {
    14. return(ss+ss);
    15. };
    16. main()
    17. {
    18. inti=2,ii;
    19. stringww("Aaa");
    20. ii=square<int>(i);
    21. cout<<i<<":"<<ii<<endl;
    22. cout<<square<string>(ww)<<endl;
    23. }

    註明:模板特例化用於當一個數據類型需要進行不同的處理和實現的情況。

  • C++ 模板無類型參數
  • [cpp] view plaincopy
    1. #include<iostream>
    2. usingnamespacestd;
    3. template<typenameT,intcount>
    4. voidloopIt(Tx)
    5. {
    6. Tval[count];
    7. for(intii=0;ii<count;ii++)
    8. {
    9. val[ii]=x++;
    10. cout<<val[ii]<<endl;
    11. }
    12. };
    13. main()
    14. {
    15. floatxx=2.1;
    16. loopIt<float,3>(xx);
    17. }

    C++ 模板默認類型參數以及無類型參數[cpp] view plaincopy

    1. #include<iostream>
    2. usingnamespacestd;
    3. template<typenameT=float,intcount=3>
    4. TmultIt(Tx)
    5. {
    6. for(intii=0;ii<count;ii++)
    7. {
    8. x=x*x;
    9. }
    10. returnx;
    11. };
    12. main()
    13. {
    14. floatxx=2.1;
    15. cout<<xx<<":"<<multIt<>(xx)<<endl;;
    16. }

    註明:multIt<>沒有指定參數類型,默認為float;

    C++ 類模板

    類模板定義:template <class T> class MyTemplateClass { ... };

    類模板特例化:template <> class MyTemplateClass <specific-data-type> { ... };

    File: Matrix2x2.hpp

    [cpp] view plaincopy

    1. #ifndefMATRIX_2X2_HPP__
    2. #defineMATRIX_2X2_HPP__
    3. usingnamespacestd;
    4. /**
    5. m(11)m(12)
    6. m(21)m(22)
    7. */
    8. template<classT>
    9. classMatrix2x2
    10. {
    11. public:
    12. Matrix2x2(Tm11,Tm12,Tm21,Tm22);//constructor
    13. Matrix2x2(Tm[2][2]);
    14. Matrix2x2();
    15. intAdd(Matrix2x2x)
    16. intMultiply(Matrix2x2x)
    17. voidPrint();
    18. Tm[2][2];
    19. };
    20. template<classT>
    21. Matrix2x2<T>::Matrix2x2(T_m11,T_m12,T_m21,T_m22)
    22. {
    23. m[0][0]=_m11;
    24. m[0][1]=_m12;
    25. m[1][0]=_m21;
    26. m[1][1]=_m22;
    27. }
    28. template<classT>
    29. Matrix2x2<T>::Matrix2x2(T_m)
    30. {
    31. m[0][0]=_m[0][0];
    32. m[0][1]=_m[0][1];
    33. m[1][0]=_m[1][0];
    34. m[1][1]=_m[1][1];
    35. }
    36. template<classT>
    37. Matrix2x2<T>::Matrix2x2()
    38. {
    39. m[0][0]=0;
    40. m[0][1]=0;
    41. m[1][0]=0;
    42. m[1][1]=0;
    43. }
    44. template<classT>
    45. Matrix2x2<T>::Add(Matrix2x2_x)
    46. {
    47. Matrix2x2<T>sum;
    48. sum.m[0][0]=m[0][0]+_x.m[0][0];
    49. sum.m[0][1]=m[0][1]+_x.m[0][1];
    50. sum.m[1][0]=m[1][0]+_x.m[1][0];
    51. sum.m[1][1]=m[1][1]+_x.m[1][1];
    52. returnsum;
    53. }
    54. template<classT>
    55. Matrix2x2<T>::Multiply(Matrix2x2_x)
    56. {
    57. Matrix2x2<T>sum;
    58. sum.m[0][0]=m[0][0]*_x.m[0][0]+m[0][1]*_x.m[1][0];
    59. sum.m[0][1]=m[0][0]*_x.m[0][1]+m[0][1]*_x.m[1][1];
    60. sum.m[1][0]=m[1][0]*_x.m[0][0]+m[1][1]*_x.m[1][0];
    61. sum.m[1][1]=m[1][0]*_x.m[0][1]+m[1][1]*_x.m[1][1];
    62. returnsum;
    63. }
    64. template<classT>
    65. Matrix2x2<T>::Print()
    66. {
    67. cout<<"|"<<m[0][0]<<""<<m[0][1]<<"|"<<endl;
    68. cout<<"|"<<m[1][0]<<""<<m[1][1]<<"|"<<endl;
    69. }
    70. #endif

    TestMatrix2x2.cpp

    [cpp] view plaincopy

    1. #include<iostream>
    2. #include"Matrix2x2.hpp"
    3. usingnamespacestd;
    4. intmain(intargc,char*argv[])
    5. {
    6. Matrix2x2<int>X(1,2,3,4);
    7. Matrix2x2<int>Y(5,6,7,8);
    8. cout<<"X:"<<endl;
    9. X.Print();
    10. cout<<"Y:"<<endl;
    11. Y.Print();
    12. Matrix2x2<int>A=X.Add(Y);
    13. cout<<"A:"<<endl;
    14. A.Print();
    15. Matrix2x2<int>B=X.Add(Y);
    16. cout<<"B:"<<endl;
    17. B.Print();
    18. }

    C++ 普通類和類模板的靜態成員變數

    普通類的靜態成員函數:

    [cpp] view plaincopy

    1. #include<iostream>
    2. usingnamespacestd;
    3. classXYZ
    4. {
    5. public:
    6. voidputPri();
    7. staticintipub;
    8. private:
    9. staticintipri;
    10. };
    11. voidXYZ::putPri()
    12. {
    13. cout<<ipri++<<endl;
    14. }
    15. //靜態成員變數初始化:
    16. intXYZ::ipub=1;
    17. intXYZ::ipri=1;
    18. main()
    19. {
    20. XYZaaa;
    21. XYZbbb;
    22. aaa.putPri();
    23. cout<<aaa.ipub<<endl;
    24. bbb.putPri();
    25. }

    類模板的靜態成員:

    [cpp] view plaincopy

    1. #include<iostream>
    2. usingnamespacestd;
    3. template<classT>
    4. classXYZ
    5. {
    6. public:
    7. voidputPri();
    8. staticTipub;
    9. private:
    10. staticTipri;
    11. };
    12. template<classT>
    13. voidXYZ<T>::putPri()
    14. {
    15. cout<<ipri++<<endl;
    16. }
    17. //靜態成員初始化:
    18. template<classT>TXYZ<T>::ipub=1;
    19. template<classT>TXYZ<T>::ipri=1.2;
    20. main()
    21. {
    22. XYZ<int>aaa;
    23. XYZ<float>bbb;
    24. aaa.putPri();
    25. cout<<aaa.ipub<<endl;
    26. bbb.putPri();
    27. }

    C++ 模板的模板參數[cpp] view plaincopy

    1. #include<iostream>
    2. usingnamespacestd;
    3. template<template<typenameT>typenameU>
    4. classXyz
    5. {
    6. ....
    7. };

    C++ 類模板和繼承

    Color.hpp (無模板的基類)

    [cpp] view plaincopy

    1. #ifndefCOLOR_HPP__
    2. #defineCOLOR_HPP__
    3. #include<string>
    4. enumeColor{none=0,red,white,blue,yellow,green,black};
    5. classColor
    6. {
    7. public:
    8. Color(eColorcolor);
    9. voidsetColor(eColorcolor);
    10. eColorgetColor(){returnmColor;};
    11. std::stringgetStrColor();
    12. protected:
    13. eColormColor;
    14. };
    15. Color::Color(eColor_color)
    16. {
    17. mColor=_color;
    18. }
    19. voidColor::setColor(eColor_color)
    20. {
    21. mColor=_color;
    22. }
    23. std::stringColor::getStrColor()
    24. {
    25. switch(mColor)
    26. {
    27. casered:
    28. return"red";
    29. casewhite:
    30. return"white";
    31. caseblue:
    32. return"blue";
    33. caseyellow:
    34. return"yellow";
    35. casegreen:
    36. return"green";
    37. caseblack:
    38. return"black";
    39. casenone:
    40. default:
    41. return"none";
    42. }
    43. }
    44. #endif

    File: Circle.hpp (模板基類)

    [cpp] view plaincopy

    1. #ifndefCIRCLE_HPP__
    2. #defineCIRCLE_HPP__
    3. #include<math.h>
    4. #include<string>
    5. #include"Color.hpp"
    6. template<typenameT>
    7. classCircle:publicColor
    8. {
    9. public:
    10. Circle(TcenterX,TcenterY,Tradius,eColorcolor);
    11. Circle(TcenterX,TcenterY,Tradius);
    12. Circle(Tradius);
    13. Tarea();
    14. Tcircumference();
    15. TgetX();
    16. TgetY();
    17. TgetRadius();
    18. protected:
    19. Tx;
    20. Ty;
    21. Tradius;
    22. };
    23. template<typenameT>
    24. Circle<T>::Circle(T_x,T_y,T_radius,eColor_color)
    25. :Color(_color)
    26. {
    27. x=_x;
    28. y=_y;
    29. radius=_radius;
    30. }
    31. template<typenameT>
    32. Circle<T>::Circle(T_x,T_y,T_radius)
    33. :Color(none)
    34. {
    35. x=_x;
    36. y=_y;
    37. radius=_radius;
    38. }
    39. template<typenameT>
    40. Circle<T>::Circle(T_radius)
    41. :Color(none)
    42. {
    43. x=const_cast<T>(0);
    44. y=const_cast<T>(0);
    45. radius=_radius;
    46. }
    47. template<typenameT>
    48. TCircle<T>::area()
    49. {
    50. returnM_PI*radius*radius;
    51. }
    52. template<typenameT>
    53. TCircle<T>::circumference()
    54. {
    55. returnconst_cast<T>(2)*M_PI*radius;
    56. }
    57. #endif

    File: testCircle.cpp

    [cpp] view plaincopy

    1. #include<iostream>
    2. #include"Circle.hpp"
    3. usingnamespacestd;
    4. intmain(intargc,char*argv[])
    5. {
    6. Circle<float>circleA(0.0,0.0,10.0,white);
    7. cout<<"Area:"<<circleA.area()<<endl;
    8. cout<<"Color:"<<circleA.getStrColor()<<endl;
    9. }

    一個模板類繼承另外一個模板類:

    File: Sphere.hpp (派生類)

    [cpp] view plaincopy

    1. #ifndefSPHERE_HPP__
    2. #defineSPHERE_HPP__
    3. #include"Circle.hpp"
    4. template<typenameT>
    5. classSphere:publicCircle<T>
    6. {
    7. public:
    8. Sphere(TcenterZ,TcenterX,TcenterY,Tradius,eColorcolor);
    9. Sphere(Tradius);
    10. Sphere();
    11. TsurfaceArea();
    12. Tvolume();
    13. TgetZ();
    14. private:
    15. Tz;
    16. };
    17. template<typenameT>
    18. Sphere<T>::Sphere(T_x,T_y,T_z,T_radius,eColor_color)
    19. :Circle<T>::Circle(_x,_y,_radius,_color)
    20. {
    21. this->z=_z;
    22. }
    23. template<typenameT>
    24. Sphere<T>::Sphere(T_radius)
    25. :Circle<T>::Circle(_radius)
    26. {
    27. this->x=const_cast<T>(0);
    28. this->y=const_cast<T>(0);
    29. this->z=const_cast<T>(0);
    30. this->radius=_radius;
    31. }
    32. template<typenameT>
    33. Sphere<T>::Sphere()
    34. {
    35. this->x=const_cast<T>(0);
    36. this->y=const_cast<T>(0);
    37. this->z=const_cast<T>(0);
    38. this->radius=const_cast<T>(1);
    39. }
    40. template<typenameT>
    41. TSphere<T>::surfaceArea()
    42. {
    43. returnconst_cast<T>(4)*M_PI*this->radius*this->radius;
    44. }
    45. template<typenameT>
    46. TSphere<T>::volume()
    47. {
    48. Tthree=3;
    49. Tfour=4;
    50. returnfour*M_PI*this->radius*this->radius*this->radius/three;
    51. }
    52. #endif

    註明:用this來顯示類的依賴

    File: testSphere.cpp

    [cpp] view plaincopy

    1. #include<iostream>
    2. #include"Sphere.hpp"
    3. usingnamespacestd;
    4. intmain(intargc,char*argv[])
    5. {
    6. Sphere<float>sphereA(0.0,0.0,0.0,10.0,blue);
    7. cout<<"Volume:"<<sphereA.volume()<<endl;
    8. cout<<"Color:"<<sphereA.getStrColor()<<endl;
    9. }
  • 推薦閱讀:

    法律工具模板 —— 遺囑(詳細版)
    柬埔寨出入境卡中文模板,柬埔寨出入境須知注意事項
    最受歡迎的內訓模板——如何煉就HR高手(建議收藏)
    std::invoke為什麼不是constexpr的?
    【代碼應用】用代碼製作詩詞模板

    TAG:函數 | 模板 |