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

C++知识点随笔(六):模板

2015-07-09 13:59 543 查看

一、函数模板

C++中模板和重载的区别:

模板是除了类型全都相同的情况下可以使用;而重载是里面的功能也有不同时使用的。

下面看一个函数模板的使用实例:

#include<iostream>
using namespace std;

typedef struct _Node
{
int m_a;
char* m_str;
}Node;

bool leftNodeBig(Node a, Node b) //结构体从大到小排
{
return (a.m_a < b.m_a);
}

template <typename T>   //整形从大到小排
bool leftBig(T t, T w)
{
return (t < w);
}

template <typename T>   //整形从小到大排
bool leftSmall(T t, T w)
{
return (t > w);
}

template <typename T>
void Bubble(T* arr, int nLength, bool (*pFun)(T a, T b)) //注意函数指针格式
{
for(int i=0;i<nLength-1;i++)
{
for (int j=0;j<nLength-1-i;j++)
{
if((*pFun)(arr[j], arr[j+1]))
{
//注意这里不能通过 ^ 交换了,因为结构体无法这样交换
//arr[j] = arr[j] ^ arr[j+1];
//arr[j+1] = arr[j] ^ arr[j+1];
//arr[j] = arr[j] ^ arr[j+1];
T temp = arr[j];
arr[j] = arr[j+1];
arr[j+1] = temp;
}
}
}
}

template <typename T>
void Show(T* arr, int nLength)
{
for(int i=0;i<nLength;i++)
{
cout << arr[i] << " ";
}
cout << endl;
}

ostream& operator<<(ostream& os, Node& node) //重载操作符保证结构体正常输出
{
os << node.m_a << " " << node.m_str;
return os;
}

int main()
{
int arr[] = {1,3,5,7,9,0,8,6,4,2};
Bubble(arr, 10, &leftBig<int>);
Show(arr, 10);

char str[] = {'b','e','f','y','s','a','c','d','l','z'};
Bubble(str, 10, &leftSmall<char>);
Show(str, 10);

Node arrNode[] = {{10,"hehe"},{9,"haha"},{100,"yaya"}};
Bubble(arrNode, 3, &leftNodeBig);
Show(arrNode,3);

system("pause");
return 0;
}


二、类模板

类模板要注意:只要我们定义了类模板的 template,那么我们只要除了这个类,一见到这个类名,就要加:

CPeople<>


其实函数模板也是一样的,定义了函数模板之后,我们在外面使用这个函数的时候也要添加类型,不加同样会报错,就像我们上面写的:

Bubble(arr, 10, &leftBig<int>);


下面我们看一段类模板的使用实例:

#include<iostream>
using namespace std;

template<typename T>
class CPeople
{
public:
//注意使用初始列表给成员变量初始化,因为我们传进来的模板T有可能是对象,前面我们也学习过,如果在类中定义一个有参数的类,那么一定要在初始化列表中给它传参。
CPeople(T t):m_t(t)
{
}
virtual void Show() //虚函数,调用子类重写的 Show()
{
cout << this->m_t << endl;
}
protected:
T m_t;
};

template<typename P, typename Q>
class CChinese : public CPeople<Q>
{
public:
CChinese(P p, Q q):CPeople<Q>(q), m_p(p) //这里一定要使用初始化列表
{
}
void Show()
{
//如果我们不重载CAA类的‘<<’操作符的话,这一句就会报错
cout << m_t << " " << this->m_p << endl;
}
private:
P m_p;
};

template<typename M>
class CAA
{
public:
CAA(M m)
{
this->m_m = m;
}
public:
M m_m;
};

template<typename N>
ostream& operator<<(ostream& os, CAA<N>& aa)  //重载CAA类的操作符
{
os << aa.m_m;
return os;
}

int main()
{
//父类指针指向子类对象,子类实现<double, char*>类型的模板
CPeople<char*> *p1 = new CChinese<double, char*>(123.456, "hello");
p1->Show();

//父类指针指向子类对象,子类将对象作为模板
CAA<double> caa(56.78);
CPeople<CAA<double>> *p2 = new CChinese<double, CAA<double>>(123.456, caa);
p2->Show();

//父类指针指向子类对象,子类将两个对象作为模板
CAA<char*> *cbb = new CAA<char*>("hello world!");
CPeople<CAA<char*>> *p3 = new CChinese<CAA<double>,CAA<char*>>(caa, *cbb);
p3->Show();

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