template<typename T>//函数模板参数列表
bool compare(T a, T b) {//函数模板 compare是模板名
cout << "bool compare(T a, T b)" << endl;
return a > b;
}
#if 0
实例化代码
bool compare<int>(int a, int b) {
cout << "bool compare(T a, T b)" << endl;
return a > b;
}
bool compare<double>(double a, double b) {
cout << "bool compare(T a, T b)" << endl;
return a > b;
}
#endif
//特例化
template<>
bool compare<const char*>(const char* a, const char* b) {
cout << "bool compare<const char*>(const char* a, const char* b)" << endl;
return strcmp(a, b) > 0;
}
//普通函数
bool compare(const char* a, const char* b) {
cout << "normal function" << endl;
return strcmp(a, b) > 0;
}
template<typename T,int SIZE>//作用域是从左括号到右括号
//SIZE模板的非类型参数 SIZE是常量不可以修改
void sort(T* arr) {
for (int i = SIZE - 1; i >= 1; i--) {
int flag= 0;
for (int j = SIZE-1; j >= SIZE-i; j--) {
if (arr[j] <arr[j - 1]) {
T tmp = arr[j];
arr[j] = arr[j - 1];
arr[j - 1] = tmp;
flag = 1;
}
}
if (flag==0) break;
}
}
int main() {
//在函数调用点根据用户提供的类型调用函数模板实例化
compare<int>(10, 20);//compare<int>才是函数名
compare<double>(10.5, 20.5);
//实参推演
compare(10, 20);//compare是模板名根据实参推演出模板的参数类型 从而实例化代码
//模板的特例化
//对于某些类型模板的代码逻辑不对,需要用户提供
compare("aa", "bb");//优先调用普通函数
compare<const char*>("aa", "bb");//优先调用模板中的特例化函数
int arr[] = { 10,20,5,91,5,26,11,45,6,11 ,30};
const int size = sizeof(arr) / sizeof(arr[0]);
sort<int,size>(arr);//模板的非类型参数
for (int val : arr) {
cout << val << " ";
}
cout << endl;
return 0;
}
//类模板
template <typename T>
class SeqStack {//SeqStack是模板名 类名=模板名+参数列表= SeqStack<T>
public:
SeqStack(int size=10) //构造函数和析构函数类名可以省去参数列表
:_pstack(new T[size])
,_top(-1)
,_size(size)
{}
~SeqStack() {
delete[] _pstack;
_pstack = nullptr;
}
SeqStack(const SeqStack<T>& src)
:_top(src._top)
, _size(src._size)
{
_pstack = new T[_size];
for (int i = 0; i <= _top; i++) {
_pstack[i] = src._pstack[i];
}
}
SeqStack<T>& operator=(const SeqStack<T>& src) {
if (this == &src) {//防止自赋值 导致内存非法访问
return *this;
}
delete[]_pstack;
_top = src._top;
_size = src._size;
_pstack = new T[_size];
for (int i = 0; i <= _top; i++) {
_pstack[i] = src._pstack[i];
}
return *this;
}
void push(const T& val) {
if (full()) {
resize();
}
_pstack[++_top] = val;
}
void pop() {
if (empty()) {
throw "stack is empty!!!";
}
--_top;
}
T top()const {
if (empty()) {
throw "stack is empty!!!";
}
return _pstack[_top];
}
bool empty()const {
return _top == -1;
}
bool full()const {
return _size == _top + 1;
}
private:
T* _pstack;
int _top;//指向栈顶元素
int _size;
void resize();
};
template<typename T>
void SeqStack<T>::resize() {
T* ptmp = new T[_size * 2];
//memcpy realloc 不能用 可能会导致浅拷贝问题
for (int i = 0; i <= _top; i++) {
ptmp[i] = _pstack[i];
}
delete[]_pstack;
_pstack = ptmp;
_size *= 2;
}
int main() {
SeqStack<int> s1;//类模板实例化 class SeqStack<int> {};
for (int i = 0; i < 20; i++) {
s1.push(rand() % 100 + 1);
}
SeqStack<int> s2 = s1;
SeqStack<int> s3(s1);
SeqStack<int> s4;
s4 = s3;
while (!s1.empty()) {
cout << s1.top() << " ";
s1.pop();
}
cout << endl;
while (!s4.empty()) {
cout << s4.top() << " ";
s4.pop();
}
cout << endl;
SeqStack<double> s5(15);
for (int i = 0; i < 20; i++) {
s5.push((rand() % 100)+ 0.6);
}
while (!s5.empty()) {
cout << s5.top() << " ";
s5.pop();
}
cout << endl;
return 0;
}
template <typename T>
class Queue {
public:
Queue(int size = 10)
:_pQue(new T[size])
,_front(0)
,_rear(0)
,_size(size)
{}
~Queue() {
delete []_pQue;
_pQue = nullptr;
}
Queue(const Queue<T>& src)
:_front(src._front)
, _rear(src._rear)
, _size(src._size)
{
_pQue = new T[_size];
for (int i=_front; i != _rear; i=(i+1)%_size) {
_pQue[i] = src._pQue[i];
}
}
Queue<T>& operator=(const Queue<T>& src) {
if (this == &src)return *this;
delete []_pQue;
_front = src._front;
_rear = src._rear;
_size = src._size;
_pQue = new T[_size];
for (int i = _front; i!= _rear; i=(i+1)%_size) {
_pQue[i] = src._pQue[i];
}
return *this;
}
void push(const T& val) {
if (full()) {
resize();
}
_pQue[_rear] = val;
_rear = (_rear + 1) % _size;
}
void pop() {
if (empty()) {
throw "queue is empty!!!";
}
_front = (_front + 1) % _size;
}
bool empty()const {
return _front == _rear;
}
bool full() const{
return _front==(_rear+1)%_size;
}
T front()const {
if (empty()) {
throw "queue is empty!!!";
}
return _pQue[_front];
}
private:
T* _pQue;
int _front;
int _rear;
int _size;
void resize();
};
template <typename T>
void Queue<T>::resize() {
T* ptmp = new T[_size * 2];
int index = 0;
for (int i = _front; i !=_rear; i=(i+1)%_size) {
ptmp[index++] = _pQue[i];
}
_front = 0;
_rear = index;
delete []_pQue;
_pQue = ptmp;
_size *= 2;
}
int main() {
int a = 0;
int b = 7;
int c = a + b;
Queue<int> q1;
for (int i = 0; i < 20; i++) {
q1.push(rand() % 100 + 1);
}
Queue<int> q2 = q1;
Queue<int> q3(q2);
Queue<int> q4;
q4 = q3;
while (!q1.empty()) {
cout << q1.front() << " ";
q1.pop();
}
cout << endl;
while (!q4.empty()) {
cout << q4.front() << " ";
q4.pop();
}
cout << endl;
return 0;
}