http://blog.csdn.net/xiaoding133/article/details/11662183 C++模板:描述
C++提供一種模板的機(jī)制來(lái)減少代碼重復(fù)。比如:對(duì)于同一樣函數(shù)使用不同的數(shù)據(jù)類型,int,double,char等。C++模板屬于“元編程”的范疇。
C++ 模板函數(shù)
1.支持不同數(shù)據(jù)類型的函數(shù)重載:
- #include <iostream>
- using namespace std;
-
- int square (int x)
- {
- return x * x;
- };
-
- float square (float x)
- {
- return x * x;
- };
-
- double square (double x)
- {
- return x * x;
- };
-
- main()
- {
- int i, ii;
- float x, xx;
- double y, yy;
-
- i = 2;
- x = 2.2;
- y = 2.2;
-
- ii = square(i);
- cout << i << ": " << ii << endl;
-
- xx = square(x);
- cout << x << ": " << xx << endl;
-
- yy = square(y);
- cout << y << ": " << yy << endl;
- }
-
2.支持所有數(shù)據(jù)類型的函數(shù)模板
- #include <iostream>
- using namespace std;
-
- template <class T>
- inline T square(T x)
- {
- T result;
- result = x * x;
- return result;
- };
-
-
-
- main()
- {
- int i, ii;
- float x, xx;
- double y, yy;
-
- i = 2;
- x = 2.2;
- y = 2.2;
-
- ii = square<int>(i);
- cout << i << ": " << ii << endl;
-
- xx = square<float>(x);
- cout << x << ": " << xx << endl;
-
- // Explicit use of template
- yy = square<double>(y);// 顯式使用模板
- cout << y << ": " << yy << endl;
-
- yy = square(y);//隱含的方式使用模板
- cout << y << ": " << yy << endl;
- }
-
注明:模板的關(guān)鍵字可以用class或者typename.
- template<class T>
- template<typename T>
兩者表達(dá)的意思是一樣的,但是我更喜歡使用后者。
可以采用兩種方式使用模板函數(shù)square<int>(value) or square(value).在模板函數(shù)的定義中,T代表數(shù)據(jù)類型。模板的聲明和定義必須在同一個(gè)文件中,如頭文件中。C語(yǔ)言的宏定義也可以實(shí)現(xiàn)函數(shù)模板的功能,#define square(x) (x * x)
但是宏沒(méi)有類型檢查,函數(shù)模板有類型檢查。
C++ 模板特例化
下面的例子字符串類型需要特殊處理,采用模板的特例化
- #include <iostream>
- using namespace std;
-
- template <class T>
- inline T square(T x)
- {
- T result;
- result = x * x;
- return result;
- };
-
- // 模板特殊化
- template <>
- string square<string>(string ss)
- {
- return (ss+ss);
- };
-
- main()
- {
- int i = 2, ii;
- string ww("Aaa");
-
- ii = square<int>(i);
- cout << i << ": " << ii << endl;
-
- cout << square<string>(ww) << endl;
- }
-
注明:模板特例化用于當(dāng)一個(gè)數(shù)據(jù)類型需要進(jìn)行不同的處理和實(shí)現(xiàn)的情況。
C++ 模板無(wú)類型參數(shù)
- #include <iostream>
- using namespace std;
-
- template <typename T, int count>
- void loopIt(T x)
- {
- T val[count];
-
- for(int ii=0; ii<count; ii++)
- {
- val[ii] = x++;
- cout << val[ii] << endl;
- }
- };
-
- main()
- {
- float xx = 2.1;
-
- loopIt<float,3>(xx);
- }
C++ 模板默認(rèn)類型參數(shù)以及無(wú)類型參數(shù)
- #include <iostream>
- using namespace std;
-
- template <typename T=float, int count=3>
- T multIt(T x)
- {
- for(int ii=0; ii<count; ii++)
- {
- x = x * x;
- }
- return x;
- };
-
- main()
- {
- float xx = 2.1;
-
- cout << xx << ": " << multIt<>(xx) << endl;;
- }
注明:multIt<>沒(méi)有指定參數(shù)類型,默認(rèn)為float;
C++ 類模板
類模板定義:template <class T> class MyTemplateClass { ... };
類模板特例化:template <> class MyTemplateClass <specific-data-type> { ... };
File: Matrix2x2.hpp
- #ifndef MATRIX_2X2_HPP__
- #define MATRIX_2X2_HPP__
-
- using namespace std;
-
- /**
- m(11) m(12)
- m(21) m(22)
- */
-
- template <class T>
- class Matrix2x2
- {
- public:
- Matrix2x2(T m11, T m12, T m21, T m22); //constructor
- Matrix2x2(T m[2][2]);
- Matrix2x2();
-
- int Add(Matrix2x2 x)
- int Multiply(Matrix2x2 x)
- void Print();
- T m[2][2];
- };
-
- template <class T>
- Matrix2x2<T>::Matrix2x2(T _m11, T _m12, T _m21, T _m22)
- {
- m[0][0] = _m11;
- m[0][1] = _m12;
- m[1][0] = _m21;
- m[1][1] = _m22;
- }
-
- template <class T>
- Matrix2x2<T>::Matrix2x2(T _m)
- {
- m[0][0] = _m[0][0];
- m[0][1] = _m[0][1];
- m[1][0] = _m[1][0];
- m[1][1] = _m[1][1];
- }
-
- template <class T>
- Matrix2x2<T>::Matrix2x2()
- {
- m[0][0] = 0;
- m[0][1] = 0;
- m[1][0] = 0;
- m[1][1] = 0;
- }
-
- template <class T>
- Matrix2x2<T>::Add(Matrix2x2 _x)
- {
- Matrix2x2<T> sum;
- sum.m[0][0] = m[0][0] + _x.m[0][0];
- sum.m[0][1] = m[0][1] + _x.m[0][1];
- sum.m[1][0] = m[1][0] + _x.m[1][0];
- sum.m[1][1] = m[1][1] + _x.m[1][1];
- return sum;
- }
-
- template <class T>
- Matrix2x2<T>::Multiply(Matrix2x2 _x)
- {
- Matrix2x2<T> sum;
- sum.m[0][0] = m[0][0] * _x.m[0][0] + m[0][1] * _x.m[1][0];
- sum.m[0][1] = m[0][0] * _x.m[0][1] + m[0][1] * _x.m[1][1];
- sum.m[1][0] = m[1][0] * _x.m[0][0] + m[1][1] * _x.m[1][0];
- sum.m[1][1] = m[1][0] * _x.m[0][1] + m[1][1] * _x.m[1][1];
- return sum;
- }
-
- template <class T>
- Matrix2x2<T>::Print()
- {
- cout << "|" << m[0][0] << " " << m[0][1] << "|" << endl;
- cout << "|" << m[1][0] << " " << m[1][1] << "|" << endl;
- }
-
- #endif
-
TestMatrix2x2.cpp
- #include <iostream>
-
- #include "Matrix2x2.hpp"
-
- using namespace std;
-
- int main(int argc, char* argv[])
- {
- Matrix2x2<int> X(1,2,3,4);
- Matrix2x2<int> Y(5,6,7,8);
-
- cout << "X:" << endl;
- X.Print();
-
- cout << "Y:" << endl;
- Y.Print();
-
- Matrix2x2<int> A = X.Add(Y);
- cout << "A:" << endl;
- A.Print();
-
- Matrix2x2<int> B = X.Add(Y);
- cout << "B:" << endl;
- B.Print();
- }
-
C++ 普通類和類模板的靜態(tài)成員變量
普通類的靜態(tài)成員函數(shù):
- #include <iostream>
-
- using namespace std;
-
-
- class XYZ
- {
- public:
- void putPri();
- static int ipub;
- private:
- static int ipri;
- };
-
-
- void XYZ::putPri()
- {
- cout << ipri++ << endl;
- }
-
- // 靜態(tài)成員變量初始化:
- int XYZ::ipub = 1;
- int XYZ::ipri = 1;
-
- main()
- {
- XYZ aaa;
- XYZ bbb;
-
- aaa.putPri();
- cout << aaa.ipub << endl;
- bbb.putPri();
- }
類模板的靜態(tài)成員:
- #include <iostream>
-
- using namespace std;
-
- template <class T>
- class XYZ
- {
- public:
- void putPri();
- static T ipub;
- private:
- static T ipri;
- };
-
- template <class T>
- void XYZ<T>::putPri()
- {
- cout << ipri++ << endl;
- }
-
- // 靜態(tài)成員初始化:
- template <class T> T XYZ<T>::ipub = 1;
- template <class T> T XYZ<T>::ipri = 1.2;
-
- main()
- {
- XYZ<int> aaa;
- XYZ<float> bbb;
-
- aaa.putPri();
- cout << aaa.ipub << endl;
- bbb.putPri();
- }
C++ 模板的模板參數(shù)
- #include <iostream>
- using namespace std;
-
- template <template <typename T> typename U>
- class Xyz
- {
- ....
- };
C++ 類模板和繼承
Color.hpp (無(wú)模板的基類)
- #ifndef COLOR_HPP__
- #define COLOR_HPP__
- #include <string>
- enum eColor { none = 0, red, white, blue, yellow, green, black };
-
- class Color
- {
- public:
- Color(eColor color);
- void setColor(eColor color);
- eColor getColor() { return mColor; };
- std::string getStrColor();
-
- protected:
- eColor mColor;
- };
-
- Color::Color(eColor _color)
- {
- mColor = _color;
- }
-
- void Color::setColor(eColor _color)
- {
- mColor = _color;
- }
-
- std::string Color::getStrColor()
- {
- switch(mColor)
- {
- case red:
- return "red";
- case white:
- return "white";
- case blue:
- return "blue";
- case yellow:
- return "yellow";
- case green:
- return "green";
- case black:
- return "black";
- case none:
- default:
- return "none";
- }
- }
- #endif
-
File: Circle.hpp (模板基類)
- #ifndef CIRCLE_HPP__
- #define CIRCLE_HPP__
- #include <math.h>
- #include <string>
-
- #include "Color.hpp"
-
- template <typename T>
- class Circle : public Color
- {
- public:
- Circle(T centerX, T centerY, T radius, eColor color);
- Circle(T centerX, T centerY, T radius);
- Circle(T radius);
-
- T area();
- T circumference();
- T getX();
- T getY();
- T getRadius();
-
- protected:
- T x;
- T y;
- T radius;
- };
-
- template <typename T>
- Circle<T>::Circle(T _x, T _y, T _radius, eColor _color)
- : Color(_color)
- {
- x = _x;
- y = _y;
- radius = _radius;
- }
-
- template <typename T>
- Circle<T>::Circle(T _x, T _y, T _radius)
- : Color(none)
- {
- x = _x;
- y = _y;
- radius = _radius;
- }
-
- template <typename T>
- Circle<T>::Circle(T _radius)
- : Color(none)
- {
- x = const_cast<T>(0);
- y = const_cast<T>(0);
- radius = _radius;
- }
-
- template <typename T>
- T Circle<T>::area()
- {
- return M_PI * radius * radius;
- }
-
- template <typename T>
- T Circle<T>::circumference()
- {
- return const_cast<T>(2) * M_PI * radius;
- }
- #endif
-
File: testCircle.cpp
- #include <iostream>
- #include "Circle.hpp"
-
- using namespace std;
-
- int main(int argc, char* argv[])
- {
- Circle<float> circleA(0.0, 0.0, 10.0, white);
- cout << "Area: " << circleA.area() << endl;
- cout << "Color: " << circleA.getStrColor() << endl;
- }
-
一個(gè)模板類繼承另外一個(gè)模板類:
File: Sphere.hpp (派生類)
- #ifndef SPHERE_HPP__
- #define SPHERE_HPP__
-
- #include "Circle.hpp"
-
- template <typename T>
- class Sphere : public Circle<T>
- {
- public:
- Sphere(T centerZ, T centerX, T centerY, T radius, eColor color);
- Sphere(T radius);
- Sphere();
-
- T surfaceArea();
- T volume();
- T getZ();
-
- private:
- T z;
- };
-
- template <typename T>
- Sphere<T>::Sphere(T _x, T _y, T _z, T _radius, eColor _color)
- : Circle<T>::Circle (_x, _y, _radius, _color)
- {
- this->z = _z;
- }
-
- template <typename T>
- Sphere<T>::Sphere(T _radius)
- : Circle<T>::Circle (_radius)
- {
- this->x = const_cast<T>(0);
- this->y = const_cast<T>(0);
- this->z = const_cast<T>(0);
- this->radius = _radius;
- }
-
- template <typename T>
- Sphere<T>::Sphere()
- {
- this->x = const_cast<T>(0);
- this->y = const_cast<T>(0);
- this->z = const_cast<T>(0);
- this->radius = const_cast<T>(1);
- }
-
- template <typename T>
- T Sphere<T>::surfaceArea()
- {
- return const_cast<T>(4) * M_PI * this->radius * this->radius;
- }
-
- template <typename T>
- T Sphere<T>::volume()
- {
- T three = 3;
- T four = 4;
- return four * M_PI * this->radius * this->radius * this->radius / three;
- }
- #endif
注明:用this來(lái)顯示類的依賴
File: testSphere.cpp
- #include <iostream>
- #include "Sphere.hpp"
-
- using namespace std;
-
- int main(int argc, char* argv[])
- {
- Sphere<float> sphereA(0.0, 0.0, 0.0,10.0, blue);
- cout << "Volume: " << sphereA.volume() << endl;
- cout << "Color: " << sphereA.getStrColor() << endl;
- }
|