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

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

2015-08-20 13:48 901 查看

C++模板:描述

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

函数模板的实例化是由编译程序在处理函数调用时自动完成的

类模板的实例化必须由程序员在程序中显式地指定

函数模板针对仅参数类型不同的函数

类模板针对仅数据成员和成员函数类型不同的类

C++ 模板函数

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

[cpp] view
plaincopy

#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
plaincopy

#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
plaincopy

#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
plaincopy

#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
plaincopy

#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
plaincopy

#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
plaincopy

#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
plaincopy

#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
plaincopy

#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
plaincopy

#include <iostream>

using namespace std;

template <template <typename T> typename U>

class Xyz

{

....

};


C++ 类模板和继承

Color.hpp (无模板的基类)

[cpp] view
plaincopy

#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
plaincopy

#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
plaincopy

#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
plaincopy

#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
plaincopy

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

}
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: