分享

C++模板:函数模板、类模板、模板与继承

 学海无涯GL 2014-09-30

 http://blog.csdn.net/xiaoding133/article/details/11662183

 C++模板:描述    

        C++提供一种模板的机制来减少代码重复。比如:对于同一样函数使用不同的数据类型,int,double,char等。C++模板属于“元编程”的范畴。

C++ 模板函数

                 1.支持不同数据类型的函数重载:

  1. #include <iostream>  
  2. using namespace std;  
  3.   
  4. int square (int x)  
  5. {  
  6.   return x * x;  
  7. };  
  8.   
  9. float square (float x)  
  10. {  
  11.   return x * x;  
  12. };  
  13.   
  14. double square (double x)  
  15. {  
  16.   return x * x;  
  17. };  
  18.   
  19. main()  
  20. {  
  21.    int    i, ii;  
  22.    float  x, xx;  
  23.    double y, yy;  
  24.   
  25.    i = 2;  
  26.    x = 2.2;  
  27.    y = 2.2;  
  28.   
  29.    ii = square(i);  
  30.    cout << i << ": " << ii << endl;  
  31.   
  32.    xx = square(x);  
  33.    cout << x << ": " << xx << endl;  
  34.   
  35.    yy = square(y);  
  36.    cout << y << ": " << yy << endl;  
  37. }  
  38.       


2.支持所有数据类型的函数模板

  1. #include <iostream>  
  2. using namespace std;  
  3.   
  4. template <class T>  
  5. inline T square(T x)  
  6. {  
  7.    T result;  
  8.    result = x * x;  
  9.    return result;  
  10. };  
  11.   
  12.   
  13.   
  14. main()  
  15. {  
  16.    int    i, ii;  
  17.    float  x, xx;  
  18.    double y, yy;  
  19.   
  20.    i = 2;  
  21.    x = 2.2;  
  22.    y = 2.2;  
  23.   
  24.    ii = square<int>(i);  
  25.    cout << i << ": " << ii << endl;  
  26.   
  27.    xx = square<float>(x);  
  28.    cout << x << ": " << xx << endl;  
  29.   
  30.    // Explicit use of template  
  31.    yy = square<double>(y);// 显式使用模板  
  32.    cout << y << ": " << yy << endl;  
  33.   
  34.    yy = square(y);//隐含的方式使用模板  
  35.    cout << y << ": " << yy << endl;  
  36. }  
  37.       

注明:模板的关键字可以用class或者typename.

  • template<class T>
  • template<typename T>

两者表达的意思是一样的,但是我更喜欢使用后者。

  • 可以采用两种方式使用模板函数square<int>(value) or square(value).
  • 在模板函数的定义中,T代表数据类型。
  • 模板的声明和定义必须在同一个文件中,如头文件中。
  • C语言的宏定义也可以实现函数模板的功能,#define square(x) (x * x)
    但是宏没有类型检查,函数模板有类型检查。

     

    C++ 模板特例化

  • 下面的例子字符串类型需要特殊处理,采用模板的特例化

    1. #include <iostream>  
    2. using namespace std;  
    3.   
    4. template <class T>  
    5. inline T square(T x)  
    6. {  
    7.    T result;  
    8.    result = x * x;  
    9.    return result;  
    10. };  
    11.   
    12. // 模板特殊化  
    13. template <>  
    14. string square<string>(string ss)  
    15. {  
    16.    return (ss+ss);  
    17. };  
    18.   
    19. main()  
    20. {  
    21.    int i = 2, ii;  
    22.    string ww("Aaa");  
    23.   
    24.    ii = square<int>(i);  
    25.    cout << i << ": " << ii << endl;  
    26.   
    27.     cout << square<string>(ww) << endl;  
    28. }  
    29.       

    注明:模板特例化用于当一个数据类型需要进行不同的处理和实现的情况。



  •  C++ 模板无类型参数

  •  

    1. #include <iostream>  
    2. using namespace std;  
    3.   
    4. template <typename T, int count>  
    5. void loopIt(T x)  
    6. {  
    7.    T val[count];  
    8.   
    9.    for(int ii=0; ii<count; ii++)  
    10.    {   
    11.        val[ii] = x++;  
    12.        cout <<  val[ii] << endl;  
    13.    }  
    14. };  
    15.   
    16. main()  
    17. {  
    18.    float xx = 2.1;  
    19.   
    20.    loopIt<float,3>(xx);  
    21. }  

     C++ 模板默认类型参数以及无类型参数

    1. #include <iostream>  
    2. using namespace std;  
    3.   
    4. template <typename T=float, int count=3>  
    5. T multIt(T x)  
    6. {  
    7.    for(int ii=0; ii<count; ii++)  
    8.    {  
    9.        x = x * x;  
    10.    }  
    11.    return x;  
    12. };  
    13.   
    14. main()  
    15. {  
    16.    float xx = 2.1;  
    17.   
    18.    cout << xx << ": " << multIt<>(xx) << endl;;  
    19. }  


    注明:multIt<>没有指定参数类型,默认为float;

     C++ 类模板

    类模板定义:template <class T> class MyTemplateClass { ... };

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

    File: Matrix2x2.hpp

    1. #ifndef MATRIX_2X2_HPP__  
    2. #define MATRIX_2X2_HPP__  
    3.   
    4. using namespace std;  
    5.   
    6. /** 
    7.     m(11)  m(12) 
    8.     m(21)  m(22) 
    9. */  
    10.   
    11. template <class T>  
    12. class Matrix2x2  
    13. {  
    14. public:  
    15.    Matrix2x2(T m11, T m12, T m21, T m22);    //constructor  
    16.    Matrix2x2(T m[2][2]);  
    17.    Matrix2x2();  
    18.   
    19.    int Add(Matrix2x2 x)  
    20.    int Multiply(Matrix2x2 x)  
    21.    void Print();  
    22.    T m[2][2];  
    23. };  
    24.   
    25. template <class T>  
    26. Matrix2x2<T>::Matrix2x2(T _m11, T _m12, T _m21, T _m22)  
    27. {  
    28.    m[0][0] = _m11;  
    29.    m[0][1] = _m12;  
    30.    m[1][0] = _m21;  
    31.    m[1][1] = _m22;  
    32. }  
    33.   
    34. template <class T>  
    35. Matrix2x2<T>::Matrix2x2(T _m)  
    36. {  
    37.    m[0][0] = _m[0][0];  
    38.    m[0][1] = _m[0][1];  
    39.    m[1][0] = _m[1][0];  
    40.    m[1][1] = _m[1][1];  
    41. }  
    42.   
    43. template <class T>  
    44. Matrix2x2<T>::Matrix2x2()  
    45. {  
    46.    m[0][0] = 0;  
    47.    m[0][1] = 0;  
    48.    m[1][0] = 0;  
    49.    m[1][1] = 0;  
    50. }  
    51.   
    52. template <class T>  
    53. Matrix2x2<T>::Add(Matrix2x2 _x)  
    54. {  
    55.     Matrix2x2<T> sum;  
    56.     sum.m[0][0] = m[0][0] + _x.m[0][0];  
    57.     sum.m[0][1] = m[0][1] + _x.m[0][1];  
    58.     sum.m[1][0] = m[1][0] + _x.m[1][0];  
    59.     sum.m[1][1] = m[1][1] + _x.m[1][1];  
    60.     return sum;  
    61. }  
    62.   
    63. template <class T>  
    64. Matrix2x2<T>::Multiply(Matrix2x2 _x)  
    65. {  
    66.     Matrix2x2<T> sum;  
    67.     sum.m[0][0] = m[0][0] * _x.m[0][0] + m[0][1] * _x.m[1][0];  
    68.     sum.m[0][1] = m[0][0] * _x.m[0][1] + m[0][1] * _x.m[1][1];  
    69.     sum.m[1][0] = m[1][0] * _x.m[0][0] + m[1][1] * _x.m[1][0];  
    70.     sum.m[1][1] = m[1][0] * _x.m[0][1] + m[1][1] * _x.m[1][1];  
    71.     return sum;  
    72. }  
    73.   
    74. template <class T>  
    75. Matrix2x2<T>::Print()  
    76. {  
    77.     cout << "|" << m[0][0] << "  " <<  m[0][1] << "|" << endl;  
    78.     cout << "|" << m[1][0] << "  " <<  m[1][1] << "|" << endl;  
    79. }  
    80.   
    81. #endif  
    82.             


    TestMatrix2x2.cpp

    1. #include <iostream>  
    2.   
    3. #include "Matrix2x2.hpp"  
    4.   
    5. using namespace std;  
    6.   
    7. int main(int argc, char* argv[])  
    8. {  
    9.     Matrix2x2<int> X(1,2,3,4);  
    10.     Matrix2x2<int> Y(5,6,7,8);  
    11.   
    12.     cout << "X:" << endl;  
    13.     X.Print();  
    14.   
    15.     cout << "Y:" << endl;  
    16.     Y.Print();  
    17.   
    18.     Matrix2x2<int> A = X.Add(Y);  
    19.     cout << "A:" << endl;  
    20.     A.Print();  
    21.   
    22.     Matrix2x2<int> B = X.Add(Y);  
    23.     cout << "B:" << endl;  
    24.     B.Print();  
    25. }  
    26.             


     

     C++ 普通类和类模板的静态成员变量

    普通类的静态成员函数:

    1. #include <iostream>  
    2.   
    3. using namespace std;  
    4.   
    5.   
    6. class XYZ  
    7. {  
    8. public:  
    9.     void putPri();  
    10.     static int ipub;  
    11. private:  
    12.     static int ipri;  
    13. };  
    14.   
    15.   
    16. void XYZ::putPri()  
    17. {  
    18.     cout << ipri++ << endl;  
    19. }  
    20.   
    21. // 静态成员变量初始化:  
    22. int XYZ::ipub = 1;  
    23. int XYZ::ipri = 1;  
    24.   
    25. main()  
    26. {  
    27.     XYZ aaa;  
    28.     XYZ bbb;  
    29.   
    30.     aaa.putPri();  
    31.     cout << aaa.ipub << endl;  
    32.     bbb.putPri();  
    33. }  

    类模板的静态成员:

    1. #include <iostream>  
    2.   
    3. using namespace std;  
    4.   
    5. template <class T>   
    6. class XYZ  
    7. {  
    8. public:  
    9.     void putPri();  
    10.     static T ipub;  
    11. private:  
    12.     static T ipri;  
    13. };  
    14.   
    15. template <class T>   
    16. void XYZ<T>::putPri()  
    17. {  
    18.     cout << ipri++ << endl;  
    19. }  
    20.   
    21. // 静态成员初始化:  
    22. template <class T> T XYZ<T>::ipub = 1;  
    23. template <class T> T XYZ<T>::ipri = 1.2;  
    24.   
    25. main()  
    26. {  
    27.     XYZ<int> aaa;  
    28.     XYZ<float> bbb;  
    29.   
    30.     aaa.putPri();  
    31.     cout << aaa.ipub << endl;  
    32.     bbb.putPri();  
    33. }  

     C++ 模板的模板参数

    1. #include <iostream>  
    2. using namespace std;  
    3.   
    4. template <template <typename T> typename U>  
    5. class Xyz  
    6. {  
    7.     ....  
    8. };  

     C++ 类模板和继承

    Color.hpp (无模板的基类)

    1. #ifndef COLOR_HPP__  
    2. #define COLOR_HPP__  
    3. #include <string>  
    4. enum eColor { none = 0, red, white, blue, yellow, green, black };  
    5.   
    6. class Color  
    7. {  
    8. public:  
    9.     Color(eColor color);  
    10.     void setColor(eColor color);  
    11.     eColor getColor() { return mColor; };  
    12.     std::string getStrColor();  
    13.   
    14. protected:  
    15.     eColor mColor;  
    16. };  
    17.   
    18. Color::Color(eColor _color)  
    19. {  
    20.    mColor = _color;  
    21. }  
    22.   
    23. void Color::setColor(eColor _color)  
    24. {  
    25.     mColor = _color;  
    26. }  
    27.   
    28. std::string Color::getStrColor()  
    29. {  
    30.     switch(mColor)  
    31.     {  
    32.        case red:  
    33.            return "red";  
    34.        case white:  
    35.            return "white";  
    36.        case blue:  
    37.            return "blue";  
    38.        case yellow:  
    39.            return "yellow";  
    40.        case green:  
    41.            return "green";  
    42.        case black:  
    43.            return "black";  
    44.        case none:  
    45.        default:  
    46.            return "none";  
    47.     }  
    48. }  
    49. #endif  
    50.             


    File: Circle.hpp (模板基类)

    1. #ifndef CIRCLE_HPP__  
    2. #define CIRCLE_HPP__  
    3. #include <math.h>  
    4. #include <string>  
    5.   
    6. #include "Color.hpp"  
    7.   
    8. template <typename T>  
    9. class Circle : public Color  
    10. {  
    11. public:  
    12.     Circle(T centerX, T centerY, T radius, eColor color);  
    13.     Circle(T centerX, T centerY, T radius);  
    14.     Circle(T radius);  
    15.   
    16.     T area();  
    17.     T circumference();  
    18.     T getX();  
    19.     T getY();  
    20.     T getRadius();  
    21.   
    22. protected:  
    23.     T x;  
    24.     T y;  
    25.     T radius;  
    26. };  
    27.   
    28. template <typename T>  
    29. Circle<T>::Circle(T _x, T _y, T _radius, eColor _color)  
    30. : Color(_color)  
    31. {  
    32.     x = _x;  
    33.     y = _y;  
    34.     radius = _radius;  
    35. }  
    36.   
    37. template <typename T>  
    38. Circle<T>::Circle(T _x, T _y, T _radius)  
    39. : Color(none)  
    40. {  
    41.     x = _x;  
    42.     y = _y;  
    43.     radius = _radius;  
    44. }  
    45.   
    46. template <typename T>  
    47. Circle<T>::Circle(T _radius)  
    48. : Color(none)  
    49. {  
    50.     x = const_cast<T>(0);  
    51.     y = const_cast<T>(0);  
    52.     radius = _radius;  
    53. }  
    54.   
    55. template <typename T>  
    56. T Circle<T>::area()  
    57. {  
    58.     return M_PI * radius * radius;  
    59. }  
    60.   
    61. template <typename T>  
    62. T Circle<T>::circumference()  
    63. {  
    64.     return const_cast<T>(2) * M_PI * radius;  
    65. }  
    66. #endif  
    67.             


    File: testCircle.cpp

     

    1. #include <iostream>  
    2. #include "Circle.hpp"  
    3.   
    4. using namespace std;  
    5.   
    6. int main(int argc, char* argv[])  
    7. {  
    8.     Circle<float> circleA(0.0, 0.0, 10.0, white);  
    9.     cout << "Area: "  << circleA.area() << endl;  
    10.     cout << "Color: " << circleA.getStrColor() << endl;  
    11. }  
    12.             


     

     一个模板类继承另外一个模板类:

    File: Sphere.hpp (派生类)

    1. #ifndef SPHERE_HPP__  
    2. #define SPHERE_HPP__  
    3.   
    4. #include "Circle.hpp"  
    5.   
    6. template <typename T>  
    7. class Sphere : public Circle<T>  
    8. {  
    9. public:  
    10.     Sphere(T centerZ, T centerX, T centerY, T radius, eColor color);  
    11.     Sphere(T radius);  
    12.     Sphere();  
    13.   
    14.     T surfaceArea();  
    15.     T volume();  
    16.     T getZ();  
    17.   
    18. private:  
    19.     T z;  
    20. };  
    21.   
    22. template <typename T>  
    23. Sphere<T>::Sphere(T _x, T _y, T _z, T _radius, eColor _color)  
    24. : Circle<T>::Circle (_x, _y, _radius, _color)  
    25. {  
    26.     this->z = _z;  
    27. }  
    28.   
    29. template <typename T>  
    30. Sphere<T>::Sphere(T _radius)  
    31. : Circle<T>::Circle (_radius)  
    32. {  
    33.     this->x = const_cast<T>(0);  
    34.     this->y = const_cast<T>(0);  
    35.     this->z = const_cast<T>(0);  
    36.     this->radius = _radius;  
    37. }  
    38.   
    39. template <typename T>  
    40. Sphere<T>::Sphere()  
    41. {  
    42.     this->x = const_cast<T>(0);  
    43.     this->y = const_cast<T>(0);  
    44.     this->z = const_cast<T>(0);  
    45.     this->radius = const_cast<T>(1);  
    46. }  
    47.   
    48. template <typename T>  
    49. T Sphere<T>::surfaceArea()  
    50. {  
    51.     return const_cast<T>(4) * M_PI * this->radius * this->radius;  
    52. }  
    53.   
    54. template <typename T>  
    55. T Sphere<T>::volume()  
    56. {  
    57.     T three = 3;  
    58.     T four  = 4;  
    59.     return four * M_PI * this->radius * this->radius * this->radius / three;  
    60. }  
    61. #endif  


    注明:用this来显示类的依赖

    File: testSphere.cpp

    1. #include <iostream>  
    2. #include "Sphere.hpp"  
    3.   
    4. using namespace std;  
    5.   
    6. int main(int argc, char* argv[])  
    7. {  
    8.     Sphere<float> sphereA(0.0, 0.0, 0.0,10.0, blue);  
    9.     cout << "Volume: " << sphereA.volume() << endl;  
    10.     cout << "Color: "  << sphereA.getStrColor() << endl;  
    11. }  


     



     

     

    • 本站是提供个人知识管理的网络存储空间,所有内容均由用户发布,不代表本站观点。请注意甄别内容中的联系方式、诱导购买等信息,谨防诈骗。如发现有害或侵权内容,请点击一键举报。
      转藏 分享 献花(0

      0条评论

      发表

      请遵守用户 评论公约

      类似文章 更多