首页 > 其他分享 >day07

day07

时间:2023-09-01 22:44:18浏览次数:39  
标签:函数 day07 类名 template 类型 模板 特化

一、类型信息运算符     typeid     在C++中typeid可以获取数据的类型,但是需要加头文件 typeinfo     find /user/inclued -name typeinfo     1、typeid是运算符,执行运算符函数,执行的返回值类型是type_info类类型对象     2、type_info中有个 name 的成员函数     3、type_info中还重载了 == 运算符,可以直接比较两个数据的类型是否相同     4、它可以区分父类指针或引用指向的是哪个子类,但是父子类之间必须构成多态
二、什么是模板     是一种自动生成代码的技术,这种技术能让程序员在编写代码时不需要考虑数据类型,因此也成为泛型编程技术 三、为什么要使用模板     1、C/C++/Java/C# 属于静态编程语言(编写->预处理->编译->汇编->链接->可执行文件)-强类型语言,静态编程语言的优点:运行速度快,缺点:代码改动后重新编译、实现代码的通用比较麻烦         Javascript/python/shell 弱类型语言 动态编程语言
    C语言实现一个通用的快排     2、C语言中的通用类型 void* + 回调函数实现的,实现难度大,使用比较麻烦     3、借助定义宏的方式实现代码通用,但是宏有一定的缺点:类型不检查、没有返回值、二义性等问题     4、借助函数重载可以实现函数代码的通用,可能会导致代码段增多,无法解决未知类型     5、综上所述,C++之父为了解决代码通用的问题,实现了模板技术,让C++摆脱数据类型的困扰
四、函数模板     1、函数模板的定义         template<typename T>         void func(T num)         {
        }         未知类型名可以取任意名字,一般约定T     2、函数模板的原理         函数模板会经历两次编译         1、检查函数模板的语法是否有错误,如果无误,也不生成函数的二进制指令,代码段没有存储该函数模板         2、根据调用者提供的实参类型再次编译检查函数模板代码,如果也没有错误,才会生成一份二进制指令存储在代码段中,所以如果函数模板没有任何以此调用则不会生成任何二进制指令,如果有不同类型的实参调用函数模板则会生成另一份二进制指令存储在代码段         这种函数模板实例化称为 "惰性实例化" 准则     3、函数模板的调用         C++编译器不会把函数模板当作一个函数的实体,而是当作生成函数实体的工具,当调用函数模板并提供了实际类型参数后才会生成函数实体         调用函数模板必须提供相应数量的参数类型             自动:编译器会自动根据实参的类型,获取函数模板的类型             手动:函数名<type1,type2,...>(实参)会根据<>中提供的类型名去生成函数实体     4、默认形参类型         template<typename T1,typename T2=int,typename T3=long>         T3 函数名(T1 arg1,T2 arg2)         {             T3 ret = arg1 + arg2;             return ret;         }         函数模板的类型参数可以像普通函数的默认形参设置形参值一样去设置默认的形参类型,靠右原则一致,但是该语法只有C++11后才支持             -std=gnu++0x    C11语法     5、函数模板的特化(特殊实例化)         模板虽好,但是不能直接解决所有类型的问题,有一些特殊类型的运算规则与普通类型的运算规则不同,例如 char* ,因此需要给这些特殊类型实现一个特殊版本,这种称为函数模板的特化         特化的方式:             1、通过 typeid()分支判断类型执行特殊的步骤                 if(typeid(T)==typeid(char*))                 {                     //实现某些功能                 }             2、实现一个特化版本                 特化的格式:                 template<>                 特化类型返回值 函数名(特化类型 形参名){}             注意:                 1、特化前,必须有一个基础版本的函数模板                 2、template<>一定要加才说明是函数模板的特化                 3、特化函数的形参基础类型要与函数模板的形参的基础类型相同,否则报错,例如函数模板中有引用,特化中也需要有                 4、编译器会优先调用函数模板中的特化版本,因此不会与基础的函数模板有冲突                 5、可以同时存在类型完全相同的普通函数、函数模板特化、函数模板,按照普通->特化->函数模板的顺序调用                 6、普通函数无论是否被调用都会生成二进制指令,但是模板特化依然遵循"惰性实例化"准则,不被调用时不生成二进制指令
    作业:实现二分查找、冒泡、插入、希尔、快排、归并、堆算法的函数模板
五、类模板     使用未知类型来设计类类型         1、类模板定义             template<typename T1,typename T2>             class 类名             {                 T1 成员变量;             public:                 T2 func(void)                 {                     T2 ret;                     return ret;                 }             };         2、类模板的使用             类模板必须先实例化才能使用,与函数模板不同的是不支持自动实例化,只能显式提供参数手动实例化                 类名<类型参数> 对象名                 类名<类型参数>* 对象指针 = new 类名<类型参数>(构造函数的实参);                 练习:实现链式队列的类模板
        3、类模板中的静态成员             类模板中允许有静态成员,与普通类的静态成员变量一样需要在类外定义             template<typename T>             class 类名             {                 static 类型名 num;             };             template<typename T> 类型名 类名<T>::num = 初始数据;             对于每个类模板实例化出来的类对象,也是共享静态成员变量         4、递归实例化             什么类型都可以是模板的类型参数,包括类模板类型             template<typename T>             class A             {                 T a;             };
            template<typename T>             class B             {                 T b;             };             B<A<int>> b; //C++11后才允许         5、类模板的默认参数类型             与函数模板的默认参数类型规则一样             template<typename T=类型名>             class A             {                 T a;             };         6、类模板的局部特化             当类模板中的成员函数不能支持所有类型时,可以针对不同类型实现类模板中的成员函数的特化版本,称为类模板的局部特化             方法1:通过typeid比较类型,通过分支语句执行特殊操作             方法2:通过实现局部特化成员函数来处理             //局部特化             template<>             int List<const char*>::find(const char* const & data)             {                 cout << "局部" << endl;                                                                 }             注意:                 1、一般在类外实现局部特化                 2、类型名的格式除了替换的typename的类型发生替换,其余所有格式都需要一致,例如常属性、引用等         7、类模板的全局特化             为特殊类型重新特化一个类模板,称为类模板的全局特化             template<>             class 类名<特殊类型>             {                 重新实现类             }         8、定义类模板和函数模板,class关键字可以替换typename

标签:函数,day07,类名,template,类型,模板,特化
From: https://www.cnblogs.com/ymy1/p/17673001.html

相关文章

  • 标准C++ -- day07
    一、虚函数、虚函数表、虚表指针、覆盖1、虚函数在成员函数前面加virtual后,该函数就称为虚函数,此时该类就会像虚进程一样多了一个虚表指针(虚函数表指针,虚指针)classBase{public:voidfunc(void){cout<<"Basefunc"<<endl;}}cout<<size......
  • day07 - 哈希表part02
    454. 四数相加II讲解classSolution{public:intfourSumCount(vector<int>&nums1,vector<int>&nums2,vector<int>&nums3,vector<int>&nums4){//mapunordered_map<int,int>map_two;i......
  • [代码随想录]Day07-字符串 part01
    题目:344.反转字符串思路:每次把最前面和最后面的交换位置即可strings库里没有反转的方法——这个反转是之后几个题的一个基础代码:双指针调换位置funcreverseString(s[]byte){l,r:=0,len(s)-1//最前面的元素,最后面的元素forl<r{s[l],s[......
  • Java学习Day07
    第六章方法一、方法1.1、概述在我们的日常生活中,方法可以理解为要做某件事情,而采取的解决办法。如:小明同学在路边准备坐车来学校学习。这就面临着一件事情(坐车到学校这件事情)需要解决,解决办法呢?可采用坐公交车或坐出租车的方式来学校,那么,这种解决某件事情的办法,我们就称为方......
  • 初学C语言day07--指针与堆内存
    什么是指针:指针是一种特殊的数据类型,使用它可以定义指针变量,指针变量中存储的是整形数据,该整型数据代表了内存的编号(地址),可以通过这个编号访问对应的内存为什么要使用指针:1、函数之间是相互独立的,但是有时候需要共享变量传参是单向值传递全局变量可以共享,但是容易命名冲突......
  • Java学习day07: 小练习
    题目1为二次方程式$ax^2+bx+c=0$设计一个名为QuadraticEquation的类,这个类包括:代表三个系数的私有数据域a、b和c;一个参数为a、b和c的构造方法;数据域a、b和c的三个get/set方法;一个名为getDiscriminant()的方法返回判别式,$b^2-4ac$;一个名为getRoot1()和getRoot2()的......
  • Day07_3.while循环
    1.while循环介绍与基本使用: 2.while循环_死循环与效率问题: 3.循环的应用: 4.while循环的结束方式一: 5.while循环的结束方式二: 6.while循环嵌套与结束案例一: 7.while循环嵌套与结束案例二: 8.while+continue: 9.while+else: 10.while+else应用案例......
  • Day07_2.深浅copy之深copy
    使用场景:如果需要拷贝一个列表,并且让两个列表的改操作完全独立开,就用深copy,否则就用浅copy深拷贝:把可变和不可变类型做了区分对待,不可变类型的指向的还是原来的值id不变,可变类型指向的是新的值id改变1.深拷贝在拷贝原列表后会产生一个新列表id不相同: 2.深拷贝可变类型数据内的......
  • Day07_1.深浅copy之浅copy
    浅拷贝原理:是把原列表第一层的内存地址不加区分的完全copy一份给新列表1.深浅copy之浅copy_1: 2.浅拷贝的id不同: 3.浅copy列表的内部元素是指向同一个的,所以单个元素的id相同: ......
  • day07 7.2 常用加密
    day077.2常用加密【1】字符串与字节反编译回来的代码有些字符串使用字节表示隐藏真正字符串Stringsalt="sign";System.out.println(Arrays.toString(salt.getBytes()));Stringv4=newString(newbyte[]{115,105,103,110});System.out.println(salt);Syste......