类模板和模板类

类模板和模板类类模板和模板类所谓类模板 实际上是建立一个通用类 其数据成员 成员函数的返回值类型和形参类型不具体指定 用一个虚拟的类型来代表 使用类模板定义对象时 系统会实参的类型来取代类模板中虚拟类型从而实现了不同类的功能 定义一个类模板与定义函数模板的格式类似 必须以关键字 template 开始 后面是尖括号括起来的模板参数 然后是类名 其格式如下 template

类模板和模板类

所谓类模板,实际上是建立一个通用类,其数据成员、成员函数的返回值类型和形参类型不具体指定,用一个虚拟的类型来代表。使用类模板定义对象时,系统会实参的类型来取代类模板中虚拟类型从而实现了不同类的功能。

定义一个类模板与定义函数模板的格式类似,必须以关键字template开始,后面是尖括号括起来的模板参数,然后是类名,其格式如下:

template 
  
    class 类名{ 类成员声明 }; 或者 template 
   
     class 类名{ 类成员声明 }; 
    
  
  1. template:是一个声明模板的关键字,它表明声明一个模板
  2. 类型参数:通常用C++标识符表示,如T、Type等,实际上是一个虚拟的类型名,现在未指定它是哪一种具体的类型,但使用类模板时,必须将类型参数实例化。
  3. typename和class的作用相同,都是表示其后面的参数是一个虚拟的类名(即类型参数).

在类声明中,欲采用通用数据类型的数据成员、成员函数的参数或返回类型前面需要加上类型参数。

如建立一个用来实现求两个数最大值的类模板

template 
  
    //模板声明,其中T为类型参数 class Compare{ public: Compare(T i,T j) { x = i; y = j; } T max() { return (x>y)?x:y; } private: T x,y; }; 
  

用类模板定义对象时,采用以下形式:

类模板名 
  <实际类型名>
    对象名[(实参表列)]; 
  

因此,使用上面求最大值的类型模板的主函数可写成:

 int main() { Compare 
  
    com1(3,7); Compare 
   
     com2(12.34,56.78); Compare 
    
      com3('a','x'); cout<<"其中的最大值是:"< 
      
     
    
  

例6.6 类模板compare的使用举例

#include 
  
    template 
   
     //模板声明,其中T为类型参数 class Compare{ public: Compare(T i,T j) { x = i; y = j; } T max() { return (x>y)?x:y; } private: T x,y; }; int main() { Compare 
    
      com1(3,7); //用类模板定义对象com1,此时T被int替代 Compare 
     
       com2(12.34,56.78); //用类模板定义对象com2,此时T被double替代 Compare 
      
        com3('a','x'); //用类模板定义对象com3,此时T被char替代 cout<<"其中的最大值是:"< 
        
       
      
     
    
  

程序运行结果是:

其中的最大值是:7 其中的最大值是:56.78 其中的最大值是:x 

在以上例子中,成员函数(其中含有类型参数)是定义类体内的。但是,类模板中的成员函数,也可以在类模板外定义。此时,若成员函数中有参数类型存在,则C++有一些特殊的规定:

(1)需要在成员函数定义之前进行模板声明; (2)在成员函数名前缀上"类名 
  <类型参数>
    ::"; 
  

在类模板外定义成员函数的一般形式如下:

temlate 
  
    函数类型 类名 
   <类型参数>
     ::成员函数名(形参表) { 函数体; } 如上题中成员函数max在类模板外定义时,应该写成: template 
    
      T Compare 
     
       ::max() { return (x>y)?x:y; } 
      
     
    
  

//例6.7 在类模板外定义成员函数函数举例。

#include 
  
    template 
   
     //模板声明,其中T为类型参数 class Compare{ public: Compare(T i,T j) { x = i; y = j; } T max(); private: T x,y; }; template 
    
      T Compare 
     
       ::max() { return (x>y)?x:y; } int main() { Compare 
      
        com1(3,7); //用类模板定义对象com1,此时T被int替代 Compare 
       
         com2(12.34,56.78); //用类模板定义对象com2,此时T被double替代 Compare 
        
          com3('a','x'); //用类模板定义对象com3,此时T被char替代 cout<<"其中的最大值是:"< 
          
         
        
       
      
     
    
  
 其中的最大值是:7 其中的最大值是:56.78 其中的最大值是:x 
 类模板 Compare 
  
    实例化成模板类:Compare 
   
     Compare 
    
      Compare 
     
       实例化模板类对象:com1 com2 com3 
      
     
    
  

例6.8 类模板Stack的使用举例。

#include 
  
    const int size=10; template 
   
     //模板声明,其中T为类型参数 class Stack{ //类模板为Stack public: void init() { tos=0; } void push(T ob); //声明成员函数push的原型,函数参数类型为T类型 T pop(); //声明成员函数pop的原型,其返回值类型为T类型 private: T stack[size]; //数组类型为T,即是自可取任意类型 int tos; }; template 
    
      //模板声明 void Stack 
     
       ::push(T ob) //在类模板体外定义成员函数push { if(tos==size) { cout<<"Stack is full"< 
      
        //模板声明 T Stack 
       
         ::pop() //在类模板体外定义成员函数push { if(tos==0) { cout<<"Stack is empty"< 
        
          s1; //用类模板定义对象s,此时T被char取代 s1.init(); s1.push('a'); s1.push('b'); s1.push('c'); for(int i=0;i<3;i++){cout<<"pop s1:"< 
         
           s2; //用类模板定义对象s,此时T被int取代 s2.init(); s2.push(1); s2.push(3); s2.push(5); for(int i=0;i<3;i++){cout<<"pop s2:"< 
           
          
         
        
       
      
     
    
  
pop s1:c pop s1:b pop s1:a pop s2:5 pop s2:3 pop s2:1 

说明:

  1. 在每一个类模板定义之前,都需要在前面加上模板声明,如
  2. 如同模板函数一样,模板类也可以有多个类型参数。

例6.9 有两个类型参数的类模板举例

#include 
  
    template 
   
     //声明模板,具有T1,T2两个类型参数 class Myclass{ //定义模板类Myclass public: Myclass( a,T b); void show(); private:  x; T y; }; template 
    
      Myclass 
     <,t>
       ::Myclass( a,T b) { x = a; y = b; } template 
      
        void Myclass 
       <,t>
         ::show() { cout<<"x="< 
        
          m1(12,0.15); //用类模板定义对象m1,此时T1,T2分别被int、double取代 Myclass 
         
           m2(12,"This a test."); //用类模板定义对象m2,此时T1,T2分别被int,char*取代 m1.show(); m2.show(); return 0; } /* 程序运行结果是: x=12,y=0.15 x=12,y=This a test. */ 
          
         
        
       
      
     
    
  
版权声明:本文内容由互联网用户自发贡献,该文观点仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请联系我们举报,一经查实,本站将立刻删除。

发布者:全栈程序员-站长,转载请注明出处:https://javaforall.net/201966.html原文链接:https://javaforall.net

(0)
上一篇 2026年3月20日 上午8:11
下一篇 2026年3月20日 上午8:11


相关推荐

  • 正确解决 Invalid module format[通俗易懂]

    正确解决 Invalid module format[通俗易懂]原言 http://blog.csdn.net/dreamtdp/article/details/8036419实现 功能:在PC的LINUX实现驱动测试,不用在2440上测试解决insmod:errorinserting’hello.ko’:-1Invalidmoduleformat第一次写Linux驱动,环境搭建了好久,第一次可能是由于GCC的版本问题,编译

    2022年8月28日
    5
  • 微生物组-宏基因组分析第8期 (报名直播课免费参加线下2020.7)[通俗易懂]

    微生物组-宏基因组分析第8期 (报名直播课免费参加线下2020.7)[通俗易懂]“福利公告:为了响应学员的学习需求,经过易生信培训团队的讨论筹备,现决定安排扩增子16S分析、宏基因组、Python课程和转录组的线上直播课。报名参加线上直播课的老师可在1年内选择参加同…

    2022年5月23日
    38
  • gcc命令和make命令[通俗易懂]

    gcc命令和make命令[通俗易懂]针对gcc,新建一个c语言文件:3.常用的有两个命令:-o将main.c预处理、编译、汇编并链接形成可执行文件main。-o选项用来指定输出文件的文件名。-S把.c文件编译成汇编文件.s查看汇编文件:其他还有把.s文件输出为.o文件的命令-c把.o文件链接为可执行文件的命令也是-o…

    2022年10月11日
    7
  • JS处理文件流

    JS处理文件流最近做一个项目 遇到了一个问题 就是导出 Excel 功能 多普通呀 多大众化 哪里都有 可惜我们后台说给我 JSON 数据 自己处理 我果断拒绝了 拒绝的里有是我菜 实现不了啊 然后后台开发看不下去了 就是转成文件流给我吧 他们那里是分布式部署 也没有办法持久化存储 遂发生了一下的故事百度没有怎么做过 肯定是百度啦 然后找打了一段代码 代码内容如下 functiondown

    2026年3月18日
    2
  • WLAN基本知识之802.11标准「建议收藏」

    WLAN基本知识之802.11标准「建议收藏」文章目录WLAN技术基础1.4802.11标准介绍1.4.1IEEE802.11协议族成员1.4.2IEEE802.11标准与WiFi的世代1.4.3802.11a/b/g差异1.4.4802.11n1.4.5802.11n关键技术1.4.6IEEE802.11ac标准1.4.7IEEE802.ax标准(又称WiFi6)1.4.8WiFi6理论速率计算WLAN技术基础1.4802.11标准介绍1.4.1IEEE802.11协议族成员IEEE805.11无线工

    2022年7月11日
    27
  • echarts地图文档_js下载本地文件

    echarts地图文档_js下载本地文件Echarts实现中国地图,含官方地图资源china.js

    2022年8月30日
    5

发表回复

您的邮箱地址不会被公开。 必填项已用 * 标注

关注全栈程序员社区公众号