C++泛型编程之类模板

时间:2022-12-21 04:22:22

泛型语义

  泛型(Generic Programming),即是指具有在多种数据类型上皆可操作的含意。泛型编
程的代表作品 STL 是一种高效、泛型、可交互操作的软件组件。
  泛型编程最初诞生于 C++中,目的是为了实现 C++的 STL(标准模板库)。其语言支
持机制就是模板(Templates)。
  模板的精神其实很简单:类型参数化(type parameterized),即,类型也是一种参数,
也是一种静多态。 换句话说, 把一个原本特定于某个类型的算法或类当中的类型信息抽掉,
抽出来做成模板参数。

 

stack类

Stack 类模板化,可以 push 和 pop 不同的数据类型。主要由几个因素需要把控。栈
中的空间元素类型,压入元素类型,弹出元素类型,三者保持一致即可。

#include <iostream> #include <stdlib.h> #include <stdio.h> #include <string.h> using namespace std; 
class Stack{
  public:   Stack(
int size=1024){     space = new int[size];     top = 0;   }

~Stack(){   delete []space; }

bool isEmpty(){
return top == 0; }
bool isFull(){
return top == 1024; }

void push(
int data){ space[top++] = data; }

int pop(){
return space[--top]; } private: int* space; int top; }; int main() {   Stack s(100);   for(int i=0; i<10; ++i){   if(!s.isFull())   s.push(i);   }

  while(
!s.isEmpty())   cout<<s.pop()<<endl;   return 0; }

 

类模板

格式:

C++泛型编程之类模板

 

应用:

ClassName<int> cn; //类模板->模板类->类对象

 

Stack类模板

#include <iostream> #include <stdlib.h> #include <stdio.h> #include <string.h> using namespace std; 
template
<typename T>class Stack {
public: Stack(
int size=1024); ~Stack(); bool isEmpty(); bool isFull(); void push(T data); T pop();

private
:
T
* space; int top; };
template
<typename T> Stack<T>::Stack(int size) {   space = new T[size];   top = 0; }
template
<typename T> Stack<T>::~Stack(){   delete []space; }

template
<typename T>bool Stack<T>::isEmpty(){   return top == 0; }

template
<typename T>bool Stack<T>::isFull(){   return top == 1024; }

template
<typename T>void Stack<T>::push(T data){   space[top++] = data; }

template
<typename T> T Stack<T>::pop(){   return space[--top]; }

int main() {   Stack
<string> s(100);   for(int i=0; i<10; ++i){     if(!s.isFull())     s.push(to_string(i)+"-abc");   }
while(
!s.isEmpty())   cout<<s.pop()<<endl;   return 0; }

   类的模板本质上就是函数模板的应用,将抽象化的函数租组织到一个类 模板 内,类名的本质就是一个命名空间。

template<typename T> class XXX从格式上区别于类,完成了对类进行抽象。

 

类模板的友元

#include <iostream> #include <istream> #include <ostream> using namespace std; //类内实现友元 template<typename T> class Complex {   friend   istream & operator>> (istream & in, Complex<T>& c)   {     in>>c.real>>c.image;     return in;   } 
  friend   ostream
& operator<< (ostream & out, Complex<T> & c)   {     cout<<"("<<c.real<<","<<c.image<<")"<<endl;     return out;   }   private:    T real;    T image; }; int main() {   Complex<double> c;   cin>>c;   cout<<c;   return 0; }

 

类外实现友元

1 )类前声明
2 )friend 类中声明 <>
3 )类外实现

#include <iostream> #include <istream> #include <ostream>
using namespace std;
//①类前声明
template
<typename T> class Complex; template<typename T> istream & operator>> (istream & in, Complex<T>& c); template<typename T> ostream & operator<< (ostream & out, Complex<T> & c);
  
template
<typename T> class Complex {

  //②freind类中声明<>   friend istream
& operator>> <>(istream & in, Complex<T>& c);   friend ostream & operator<< <>(ostream & out, Complex<T> & c); private:   T real;   T image; };

//③类外实现
template
<typename T> istream & operator>> (istream & in, Complex<T>& c) {   in>>c.real>>c.image;   return in; }
template<typename T> ostream & operator<< (ostream & out, Complex<T> & c) 
{   
  cout<<"("<<c.real<<","<<c.image<<")"<<endl;   
  
return out;
}

int main() {   Complex
<double> c;   cin>>c;   cout<<c;   return 0; }

 

hpp

《C++编程思想》第 15 章(第 300 页):
  模板定义很特殊。由 template<…> 处理的任何东西都意味着编译器在当时不为它分
配存储空间, 它一直处于等待状态直到被一个模板实例告知。 在编译器和连接器的某一处,
有一机制能去掉指定模板的多重定义。所以为了容易使用,几乎总是在头文件中放置全部
的模板声明和定义,文件后缀为.hpp。