C++泛型基础

1.泛型的基本思想

泛型编程(Generic Programming)是一种语言机制,通过它可以实现一个标准的容器库。像类一样,泛型也是一种抽象数据类型,但是泛型不属于面向对象,它是面向对象的补充和发展。
在面向对象编程中,当算法与数据类型有关时,面向对象在对算法的抽象描述方面存在一些缺陷。
比如对栈的描述:
class stack
{

push(参数类型)  //入栈算法

pop(参数类型)   //出栈算法

}
如果把上面的伪代码看作算法描述,没问题,因为算法与参数类型无关。但是如果把它写成可编译的源代码,就必须指明是什么类型,否则是无法通过编译的。使用重载来解决这个问题,即对N种不同的参数类型写N个push和pop算法,这样是很麻烦的,代码也无法通用。
若对上面的描述进行改造如下:
首先指定一种通用类型T,不具体指明是哪一种类型。
class stack<参数模板 T>
{

push(T)  //入栈算法

pop(T)   //出栈算法

}

这里的参数模板T相当于一个占位符,当我们实例化类stack时,T会被具体的数据类型替换掉。
若定义对象S为statc类型,在实例化S时若我们将T指定int型则:
这时候类S就成为:
class S
{
    push(int)  //入栈算法
    pop(int)   //出栈算法
}
这时我可以称class stack<参数模板 T>是类的类,通过它可以生成具体参数类型不同的类。

2.泛型在C++中的应用

泛型在C++中的主要实现为模板函数和模板类。
通常使用普通的函数实现一个与数据类型有关的算法是很繁琐的,比如两个数的加法,要考虑很多类型:
int add(int a,int b) { return a+b; }
float add(float a,float b) { return  a+b; }
。。。。
虽然在C++中可以通过函数重载来解决这个问题,但是反复写相同算法的函数是比较辛苦的,更重要的是函数重载是静态编译,运行时占用过多内存。
在此我们可以用C++的模板函数来表达通用型的函数,如下:
template<typename T> // 模板声明
T add(T a,T b) { return a+b; }  // 注意形参和返回值的类型
这时C++编译器会根据add函数的参数类型来生成一个与之对应的带具体参数类型的函数并调用。
例如:
#include <iostream>
using namespace std;
template <typename T>
T add(T a,T b)  //注意形参和返回类型
{   
 return a+b;

void main()
{
    int num1, num2, sum; 
    cin>>num1>>num2;
    sum=add(num1,num2); //用int匹配模版参数T,若sum,num1,num2类型不一致则无法匹配。
    cout<<sum;
}

3.函数模板的性质

1) 函数模板并不是真正的函数,它只是C++编译生成具体函数的一个模子。
2) 函数模板本身并不生成函数,实际生成的函数是替换函数模板的那个函数,比如上例中的add(sum1,sum2),
    这种替换是编译期就绑定的。
3) 函数模板不是只编译一份满足多重需要,而是为每一种替换它的函数编译一份。
4) 函数模板不允许自动类型转换。
5) 函数模板不可以设置默认模板实参。比如template <typename T=0>不可以。

4.C++模版函数的语法

template  <typename 模版参数列表…>
函数返回类型 函数名(形参列表…)
上面两行可以合并成一行。
例如:
下面的几种写法是等效的并且class 和typename是可以互换的。
template  <typename T1, typename T2>
T1 fun(T1, T2, int )
{  //…..}
template  <typename T1,T2>  T1 fun(T1, T2, int )
{  //…..}
template  <class T1, class T2>
 T1 fun(T1, T2, int )
{  //…..}
template  <class T1,T2>  T1 fun(T1, T2, int )
{  //…..}

5.C++模版类的语法

template  <class 模版参数列表…>
class 类名
{ //类体}
成员的实现…
例如:
//类声明部分,有两个模板参数T1,T2
template  <class T1, class T2 >  
class A {
   private:
   int a;
  T1 b;  //成员变量也可以用模板参数
  public: 
  int fun1(T1 x, int y );
 T2 fun2(T1 x, T2 y);
}
//类实现部分
template  <class T1, class T2 >
int A<T1>:: fun1(T1 x, int y ){//实现…… }
 template  <class T1, class T2 >
T2 A<T1,T2>:: fun2(T1 x, T2 y) {//实现…… }
 //使用类A
 int main( ) {
 //定义对象a,并用int替换T1, float替换T2
   A<int, float>  a;
   //实例化a,调用a的属性和方法……
}
由上例可以看出, 类模板参数T1,T2对类的成员变量和成员函数均有效。
在C++编程中,当你要实现的一个类的某些成员函数和成员变量的算法跟数据类型有关,可以考虑用类模板,且C++版的数据结构算法大都用类模板实现。

6.类模板的性质

1) 类模板不是真正的类,它只是C++编译器生成具体类的一个模子。
2) 类模板可以设置默认模板实参。

时间: 2024-10-10 14:18:01

C++泛型基础的相关文章

一个小栗子聊聊JAVA泛型基础

背景 周五本该是愉快的,可是今天花了一个早上查问题,为什么要花一个早上?我把原因总结为两点: 日志信息严重丢失,茫茫代码毫无头绪. 对泛型的认识不够,导致代码出现了BUG. 第一个原因可以通过以后编码谨慎的打日志来解决,我们今天主要来一起回顾下JAVA泛型基础. 一个小栗子 先看下面一个例子,test1实例化一个List容器的时候没有指定泛型参数,那么我们可以往这个容器里面放入任何类型的对象,这样是不是很爽?但是当我们从容器中取出容器中的对象的时候我们必须小心翼翼,因为容器中的对象具有运行时的类

C++泛型基础学习

转载http://blog.csdn.net/xinzheng_wang/article/details/6674847 泛型的基本思想:泛型编程(Generic Programming)是一种语言机制,通过它可以实现一个标准的容器库.像类一样,泛型也是一种抽象数据类型,但是泛型不属于面向对象,它是面向对象的补充和发展.在面向对象编程中,当算法与数据类型有关时,面向对象在对算法的抽象描述方面存在一些缺陷.比如对栈的描述:class stack{ push(参数类型)  //入栈算法 pop(参数

编程基础系列--之--泛型基础,检索枚举,以及在抽象工厂中的使用

万丈高楼平地起,基础是重中之重,虽说基础在生产环境下作用并不大,但是扎实的基础是你不断学习的保障.今天继续探讨基础--泛型. 刚刚步入社会,开始自己的第一份工作,在工作中遇到这样一个业务场景:我需要将枚举字段存到数据库中,数据库是一位大佬设计的,枚举字段是英文,对应的值是int类型,我要在界面上显示的值却要是中文,这个问题其实并不难,按照我一开始的思路,我只需要根据数据库中存的值查询出来,必要的时候手动将英文转换成中文就可以了.但是在实际做项目的过程中才发现.这样设计的程序太死板而且特别麻烦.有

《Java架构筑基》从Java基础讲起——泛型基础

一.泛型的概述 1.1 泛型由来 我们的集合可以存储多种数据类型的元素,那么在存储的时候没有任何问题,但是在获取元素,并向下转型的时候,可能会存在一个错误,而这个错误就是ClassCastException . 很显然,集合的这种可以存储多种数据类型的元素的这个特点,不怎么友好 , 程序存在一些安全隐患,那么为了出来这种安全隐患,我们应该限定一个集合存储元素的数据类型,我们只让他存储统一中数据类型的元素,那么在做向下转型的是就不会存在这种安全隐患了. 怎么限定集合只能给我存储同一种数据类型的元素

Java:泛型基础

泛型 引入泛型 传统编写的限制: 在Java中一般的类和方法,只能使用具体的类型,要么是基本数据类型,要么是自定义类型.如果要编写可以应用于多种类型的代码,这种刻板的限制就会束缚很多! 解决这种限制的三种方法: 1.多态:将方法的参数类型设为基类,那么该方法就可以接收从这个基类导出的任何类作为参数. class Primary{} //定义基类 class Test() { public void f(Primary p) {...} } 2.方法的参数使用接口:任何实现了该接口的类都可以满足该

2.java泛型基础

Java泛型(generics)是JDK 5中引入的一个新特性,允许在定义类和接口的时候使用类型参数(type parameter).声明的类型参数在使用时用具体的类型来替换.泛型最主要的应用是在JDK 5中的新集合类框架中.对于泛型概念的引入,开发社区的观点是褒贬不一.从好的方面来说,泛型的引入可以解决之前的集合类框架在使用过程中通常会出现的运行时刻类型错误,因为编译器可以在编译时刻就发现很多明显的错误.而从不好的地方来说,为了保证与旧有版本的兼容性,Java泛型的实现上存在着一些不够优雅的地

java的泛型基础入门

1.泛型的作用 防止随意的放置任何的对象,使用泛型后只能按我们使用时指定的类型添加以及会相应的进行编译时检查,在编译检查后会去除相应的泛型信息(运行时没有这个信息了),在类型转换的也会自动的相应的转换为相应的信息 public class GenenricyDemo1 { public static <T> T test1(T t){ return t; } public <T> T test2(T t){ return t; } public static void main(S

泛型基础复习

泛型详解 概念:泛型即“参数化类型”:提到参数,最熟悉的就是定义方法时有形参,然后调用此方法时传递实参.所谓参数化类型就将类型由原来具体类型参数化,类似于方法中的变量参数,此时类型也定义成参数形式(类型形参),然后在使用时传入具体的类型(类型实参). Java中的泛型,只在编译阶段有效.泛型类型在逻辑上看以看成是多个不同的类型,实际上都是相同的基本类型,编译阶段以后会去泛型化. 泛型的三种使用方式为:泛型类.泛型接口.泛型方法: 示例代码 public class FanXingTest2 {

java之 ------ 泛型【从基础到加强】

泛型 基础篇 一.为什么要泛型 1.原因 先看一个集合的例子(至于集合,前面有讲解,集合详解链接,不懂得可以先去看看那篇) import java.util.ArrayList; import java.util.Collection; import java.util.HashSet; import java.util.Iterator; import cn.hncu.bean.Person; public class CollectionDemo { public static void m