c 模板:描述
c 提供一种模板的机制来减少代码重复。比如:对于同一样函数使用不同的数据类型,int,double,char等。c 模板属于“元编程”的范畴。
c 模板函数
1.支持不同数据类型的函数重载:
#include
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
using namespace std;
template
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(i);
cout << i << ": " << ii << endl;
xx = square(x);
cout << x << ": " << xx << endl;
// explicit use of template
yy = square(y);// 显式使用模板
cout << y << ": " << yy << endl;
yy = square(y);//隐含的方式使用模板
cout << y << ": " << yy << endl;
}
注明:模板的关键字可以用class或者typename.
- template
- template
两者表达的意思是一样的,但是我更喜欢使用后者。
- 可以采用两种方式使用模板函数square
(value) or square(value). - 在模板函数的定义中,t代表数据类型。
- 模板的声明和定义必须在同一个文件中,如头文件中。
- c语言的宏定义也可以实现函数模板的功能,#define square(x) (x * x)
但是宏没有类型检查,函数模板有类型检查。c 模板特例化
-
下面的例子字符串类型需要特殊处理,采用模板的特例化
-
#include
using namespace std; template inline t square(t x) { t result; result = x * x; return result; }; // 模板特殊化 template <> string square (string ss) { return (ss ss); }; main() { int i = 2, ii; string ww("aaa"); ii = square (i); cout << i << ": " << ii << endl; cout << square (ww) << endl; } 注明:模板特例化用于当一个数据类型需要进行不同的处理和实现的情况。
-
c 模板无类型参数
-
#include
using namespace std; template void loopit(t x) { t val[count]; for(int ii=0; ii (xx); } c 模板默认类型参数以及无类型参数
#include
using namespace std; template t multit(t x) { for(int ii=0; ii (xx) << endl;; } 注明:multit<>没有指定参数类型,默认为float;
c 类模板
类模板定义:template
class mytemplateclass { ... }; 类模板特例化:template <> class mytemplateclass
{ ... }; file: matrix2x2.hpp
#ifndef matrix_2x2_hpp__ #define matrix_2x2_hpp__ using namespace std; /** m(11) m(12) m(21) m(22) */ template
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 matrix2x2 ::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 matrix2x2 ::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 matrix2x2 ::matrix2x2() { m[0][0] = 0; m[0][1] = 0; m[1][0] = 0; m[1][1] = 0; } template matrix2x2 ::add(matrix2x2 _x) { matrix2x2 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 matrix2x2 ::multiply(matrix2x2 _x) { matrix2x2 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 matrix2x2 ::print() { cout << "|" << m[0][0] << " " << m[0][1] << "|" << endl; cout << "|" << m[1][0] << " " << m[1][1] << "|" << endl; } #endif testmatrix2x2.cpp
#include
#include "matrix2x2.hpp" using namespace std; int main(int argc, char* argv[]) { matrix2x2 x(1,2,3,4); matrix2x2 y(5,6,7,8); cout << "x:" << endl; x.print(); cout << "y:" << endl; y.print(); matrix2x2 a = x.add(y); cout << "a:" << endl; a.print(); matrix2x2 b = x.add(y); cout << "b:" << endl; b.print(); } c 普通类和类模板的静态成员变量
普通类的静态成员函数:
#include
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
using namespace std; template class xyz { public: void putpri(); static t ipub; private: static t ipri; }; template void xyz ::putpri() { cout << ipri << endl; } // 静态成员初始化: template t xyz ::ipub = 1; template t xyz ::ipri = 1.2; main() { xyz aaa; xyz bbb; aaa.putpri(); cout << aaa.ipub << endl; bbb.putpri(); } c 模板的模板参数
#include
using namespace std; template typename u> class xyz { .... }; c 类模板和继承
color.hpp (无模板的基类)
#ifndef color_hpp__ #define color_hpp__ #include
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
#include #include "color.hpp" template 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 circle ::circle(t _x, t _y, t _radius, ecolor _color) : color(_color) { x = _x; y = _y; radius = _radius; } template circle ::circle(t _x, t _y, t _radius) : color(none) { x = _x; y = _y; radius = _radius; } template circle ::circle(t _radius) : color(none) { x = const_cast (0); y = const_cast (0); radius = _radius; } template t circle ::area() { return m_pi * radius * radius; } template t circle ::circumference() { return const_cast (2) * m_pi * radius; } #endif file: testcircle.cpp
#include
#include "circle.hpp" using namespace std; int main(int argc, char* argv[]) { circle 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
class sphere : public circle { 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 sphere ::sphere(t _x, t _y, t _z, t _radius, ecolor _color) : circle ::circle (_x, _y, _radius, _color) { this->z = _z; } template sphere ::sphere(t _radius) : circle ::circle (_radius) { this->x = const_cast (0); this->y = const_cast (0); this->z = const_cast (0); this->radius = _radius; } template sphere ::sphere() { this->x = const_cast (0); this->y = const_cast (0); this->z = const_cast (0); this->radius = const_cast (1); } template t sphere ::surfacearea() { return const_cast (4) * m_pi * this->radius * this->radius; } template t sphere ::volume() { t three = 3; t four = 4; return four * m_pi * this->radius * this->radius * this->radius / three; } #endif 注明:用this来显示类的依赖
file: testsphere.cpp
#include
#include "sphere.hpp" using namespace std; int main(int argc, char* argv[]) { sphere spherea(0.0, 0.0, 0.0,10.0, blue); cout << "volume: " << spherea.volume() << endl; cout << "color: " << spherea.getstrcolor() << endl; }