您的位置:首页 > 编程语言 > C语言/C++

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

2016-08-24 10:05 295 查看

 C++模板:描述    

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

C++ 模板函数

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

[cpp]
view plain
copy

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

[cpp]
view plain
copy

#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++ 模板特例化

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

[cpp]
view plain
copy

#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++ 模板无类型参数

 

[cpp]
view plain
copy

#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++ 模板默认类型参数以及无类型参数

[cpp]
view plain
copy

#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

[cpp]
view plain
copy

#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

[cpp]
view plain
copy

#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++ 普通类和类模板的静态成员变量

普通类的静态成员函数:

[cpp]
view plain
copy

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

类模板的静态成员:

[cpp]
view plain
copy

#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++ 模板的模板参数

[cpp]
view plain
copy

#include <iostream>  
using namespace std;  
  
template <template <typename T> typename U>  
class Xyz  
{  
    ....  
};  

 C++ 类模板和继承

Color.hpp (无模板的基类)

[cpp]
view plain
copy

#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 (模板基类)

[cpp]
view plain
copy

#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

 

[cpp]
view plain
copy

#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 (派生类)

[cpp]
view plain
copy

#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

[cpp]
view plain
copy

#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;  
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: