首页 诗词 字典 板报 句子 名言 友答 励志 学校 网站地图
当前位置: 首页 > 教程频道 > 开发语言 > C++ >

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

2013-09-14 
C++模板:函数模板、类模板、模板与继承C模板:描述C提供一种模板的机制来减少代码重复。比如:对于同一样函数使

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

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

C++ 模板函数

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

#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.支持所有数据类型的函数模板

#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;}    

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

template<class T> template<typename T>

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

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

 

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;}    

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



 C++ 模板无类型参数

 

#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++ 模板默认类型参数以及无类型参数
#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<>没有指定参数类型,默认为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++ 普通类和类模板的静态成员变量

普通类的静态成员函数:

#include <iostream>using namespace std;class XYZ{public:    void putPri();    static int ipub;private:    static int ipri;};void XYZ::putPri(){    cout << ipri++ << endl;}// 静态成员变量初始化:int XYZ::ipub = 1;int XYZ::ipri = 1;main(){    XYZ aaa;    XYZ bbb;    aaa.putPri();    cout << aaa.ipub << endl;    bbb.putPri();}

类模板的静态成员:

#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;}// 静态成员初始化: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++ 模板的模板参数
#include <iostream>using namespace std;template <template <typename T> typename U>class Xyz{    ....};
 C++ 类模板和继承

Color.hpp (无模板的基类)

#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;}          


 

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

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来显示类的依赖

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;}


 



 

 

热点排行