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

C++模板:描述    

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

C++ 模板函数

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

[cpp]  view plain  copy
  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.支持所有数据类型的函数模板

[cpp]  view plain  copy
  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++ 模板特例化

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

[cpp]  view plain  copy
  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++ 模板无类型参数

 

[cpp]  view plain  copy
  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++ 模板默认类型参数以及无类型参数

[cpp]  view plain  copy
  1. #include <iostream>  
  2. using namespace std;  
  3.   
  4. template <typename T=floatint 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

[cpp]  view plain  copy
  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

[cpp]  view plain  copy
  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++ 普通类和类模板的静态成员变量

普通类的静态成员函数:

[cpp]  view plain  copy
  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. }  

类模板的静态成员:

[cpp]  view plain  copy
  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++ 模板的模板参数

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

 C++ 类模板和继承

Color.hpp (无模板的基类)

[cpp]  view plain  copy
  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 (模板基类)

[cpp]  view plain  copy
  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

 

[cpp]  view plain  copy
  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 (派生类)

[cpp]  view plain  copy
  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

[cpp]  view plain  copy
  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. }  


 转发源:https://blog.csdn.net/xiaoding133/article/details/11662183

  • 0
    点赞
  • 3
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值