类模板
来源:互联网 发布:node.js 知乎 编辑:程序博客网 时间:2024/06/07 12:24
一.建立一个stack类
#include<iostream>
const int MAX=10;
using namespace std;
template<typename T>
class Stack
{
private:
T stack[MAX];
int top;
public:
Stack()
{
top=0;
}
void push(T const &s);
T& pop();
T& GetTop() const;
int IsEmpty() const ;
};
template<typename T> //函数定义时别忘了带上这个
void Stack<T>::push(T const &s)
{
stack[top++]=s;
}
template<typename T>
T& Stack<T>::pop()
{
return stack[--top];
}
template<typename T>
T& Stack<T>::GetTop() const
{
return stack[top-1];
}
template<typename T>
int Stack<T>::IsEmpty() const
{
return top==0;
}
//主函数
int main(int argc,char **argv)
{
Stack<int> s;
for(int i=0;i<10;i++)
s.push(i);
while(!s.IsEmpty())
{
cout<<s.pop();
}
cout<<endl;
return 0;
}
二.模板的特化(类模板不允许重载)
template<typename T1,typename T2>
class MyClass{...};
//局部特化:1
template<typename T>//注意特化的时候类后面加了<...>
class MyClass<T,T>{...};
//局部特化:2
template<typename T>
class MyClass<T,int>{...};
//局部特化:3
template<typename T1,typename T2>
class MyClass<T1*,T2*>{...};
(注意:特化的模板属于非特化模板的子集,即非特化的模板包含了所有特化的情况)
MyClass<int,float>mt=======>MyClass<T1,T2>
MyClass<int,int>mt=======>MyClass<T,T>
MyClass<float,int>mt====>MyClass<T,int>//优先考虑特化模板(其实非特化也满足)
MyClass<int*,float*>=======>MyClass<T1*,T2*>//同上
三.另外一个例子
#include<iostream>
using namespace std;
template<typename T1,typename T2>
class Myclass{
private:
T1 a;
T2 b;
public:
Myclass(T1 m,T2 n)
{
a=m;
b=n;
cout<<"fun1 was called!"<<endl;
}
};
//局部化1
template<typename T>
class Myclass<T,T>{
private:
T a;
T b;
public:
Myclass<T,T>(T m,T n)
{
a=m;
b=n;
cout<<"fun2 was called!"<<endl;
}
};
//局部特化2
template<typename T1>
class Myclass<T1,char>{
private:
T1 a;
char b;
public:
Myclass<T1,char>(T1 m,char n)
{
a=m;
b=n;
cout<<"fun3 was called!"<<endl;
}
};
//局部特化3
template<typename T1,typename T2>
class Myclass<T1*,T2*>{
private:
T1* a;
T2* b;
public:
Myclass<T1*,T2*>(T1* m,T2* n)
{
a=m;
b=n;
cout<<"fun4 was called!"<<endl;
}
};
int main(int argc,char *argv[])
{
int a=1,*pa=&a;
float b=2.3,*pb=&b;
Myclass<int,float> s1(1,2.3);
Myclass<int,char> s2(1,'a');
Myclass<int,int> s3(1,2);
Myclass<int *,float *> s4(pa,pb);
return 0;
}
//g++ 4.6.1
//fun1 was called!
//fun3 was called!
//fun2 was called!
//fun4 was called!
四.模板的继承
1.非依赖基类,即基类的模板参数不依赖派生类的模板参数。
#include<iostream>
using namespace std;
template<typename T>
class A{
private:
T a;
public:
A(T m)
{
a=m;
}
void printa()
{
cout<<"A::a="<<a<<endl;
}
};
template<typename T>
class B:public A<int>{
private:
T b;
public:
B(T n,int i):A<int>(i)
{
b=n;
}
void printb()
{
printa();
cout<<"B::b="<<b<<endl;
}
};
int main(int argc,char *argv[])
{
A<float> a(1.5);
B<int> b(2,4);
a.printa();
b.printb();
return 0;
}
//A::a=1.5
//A::a=4
//B::b=2
2.依赖基类,即基类的模板参数依赖于派生类的模板参数(注意:此时在派生类中调用基类的成员,要显式使用this指针或Base::作用域)
#include<iostream>
using namespace std;
template<typename T>
class A{
private:
T a;
public:
A(T m)
{
a=m;
}
void printa()
{
cout<<"A::a="<<a<<endl;
}
};
template<typename T1,typename T2>
class B:public A<T2>{
private:
T1 b;
public:
B(T1 n,T2 m):A<T2>(m)
{
b=n;
}
void printb()
{
this->printa(); //这里要使用this指针
cout<<"B::b="<<b<<endl;
}
};
int main(int argc,char *argv[])
{
B<int,int> b1(2,4);
B<int,float> b2(2,3.5);
b1.printb();
b2.printb();
return 0;
}
//A::a=4
//B::b=2
//A::a=3.5
//B::b=2
四.模板参数小技巧
1.模板的参数还可以是非类型(注意:非类型不可以是浮点double和常量字符串指针)
template<typename T,int MAX>
class Stack{
private:
T stack[MAX];
......
public:
void push(..);
......
};
//在定义的时候:
template<typename T,int MAX>
void Stack<T,MAX>push(..){..};//直接带入MAX
2.模板的参数来定义类成员
template<typename T >
class Stack{
private:
typename T::iterator it;//当没有typename时T将被认为是静态成员
T stack[MAX];
......
public:
void push(..);
......
};
3.模板的参数还可有默认值
template<typename T= int>//默认值为int
class Stack{
private:
T stack[MAX];
......
public:
void push(..);
......
};
五.模板参数
1.成员函数模板不能声明为虚函数,因为虚函数的调用机制使用的大小固定的虚函数表。
2.模板参数还可以是类或函数模板
template<templateT,template<typename T1,typename T2> class A>
class B{
A<T,int>bb;
.....//注意这里不能再使用T1,T2了,如T1 data; (错误)
}
所以可以简化为
template<template T,template<typename ,typename > class A>
class B{
A<T,int> bb;
.....//注意这里不能再使用T1,T2了,如T1 data; (错误)
}
3.缺省参数依赖于前面的模板参数
template<typename T,typename Allocator=allocator<T> >//注意这里空格
calssList;
......
- 函数模板、类模板
- 模板 - 类模板
- 模板函数,模板类
- 模板的模板类
- 类模板(函数模板)
- 模板之---类模板
- C++模板:模板类
- 函数模板 类模板
- 函数模板、类模板
- C++模板学习(函数模板+类模板)
- 模板——函数模板、类模板
- 模板 Templates 模板函数 模板类
- C++模板(类模板、函数模板)
- 模板之类模板(数组类模板)
- 类模板
- 类模板
- 类模板
- 类模板
- .gitignore
- java return测试
- js动态添加外部js(顶)
- Row Format and Size【每日一译】--20121123
- 回车提交
- 类模板
- 浏览器是怎么工作的(前端必读)
- C++面向对象总结
- android install INSTALL_FAILED_MISSING_SHARED_LIBRARY
- Linux 下的压缩和打包命令
- Oracle11g如何修改最大连接数
- 一个整型数组里除了两个数字之外,其他的数字都出现了两次。 请写程序找出这两个只出现一次的数字。
- 单选框状态的判断,当你做选择题时,没选择任何答案不让做下一道题,就会遇到这种问题了!
- QCon所见和所得:杭州QCon热门技术话题分享