| |
|
开发:
C++知识库
Java知识库
JavaScript
Python
PHP知识库
人工智能
区块链
大数据
移动开发
嵌入式
开发工具
数据结构与算法
开发测试
游戏开发
网络协议
系统运维
教程: HTML教程 CSS教程 JavaScript教程 Go语言教程 JQuery教程 VUE教程 VUE3教程 Bootstrap教程 SQL数据库教程 C语言教程 C++教程 Java教程 Python教程 Python3教程 C#教程 数码: 电脑 笔记本 显卡 显示器 固态硬盘 硬盘 耳机 手机 iphone vivo oppo 小米 华为 单反 装机 图拉丁 |
-> C++知识库 -> C++之模板——初阶 -> 正文阅读 |
|
[C++知识库]C++之模板——初阶 |
目录 一. 泛型编程以实现一个交换函数为例,当我们要实现一个可以交换各种类型的交换的函数,我们一般会像以下代码一样:
但是使用函数重载仍然有它的缺点:
所以这个时候就出现了泛型编程。 泛型编程:编写与类型无关的通用代码,是代码复用的一种手段。模板是泛型编程的基础。 二. 函数模板1.?函数模板概念
2. 函数模板格式
3. 函数模板原理函数模板是一个蓝图,它本身并不是函数,是编译器用使用方式产生特定具体类型函数的模具。 所以其实模板就是将本来应该我们做的重复的事情交给了编译器 在编译器编译阶段,对于模板函数的使用,编译器需要根据传入的实参类型来推演生成对应类型 的函数以供调用。 比如:当用int类型使用函数模板时,编译器通过对实参类型的推演,将T确定为int类型,然后产生一份专门处理int类型的代码,对于字符类型也是如此。 所以,这里我们可以知道,其实三个swap函数其实是调用了三个函数,并不是调用了一个函数。 需要注意的是:函数模板类型虽然一般是编译器根据实参传递给形参,推演出来的,但是,如果不能自动推演,那么我们就需要显示实例化,指定模板参数,如下情况: 这里编译器就无法推导出T,需要我们自己去指定模板参数,如下: 我们就会发现,编译通过了,所以并不是说函数模板一定就是使用隐式实例化,特定场景也需要使用显示实例化。 4.?函数模板的实例化用不同类型的参数使用函数模板时,称为函数模板的实例化。 注:实例化是在编译阶段进行的(可以查看编译完成的.s文件)。 模板参数实例化分为:隐式实例化和显式实例化。
如果类型不匹配,编译器会尝试进行隐式类型转换,如果无法转换成功编译器将会报错。 5.?模板参数的匹配原则
三. 类模板1.?类模板的定义格式
具体使用场景:
2. 类模板的实例化类模板实例化与函数模板实例化不同,必须显示实例化,类模板实例化需要在类模板名字后跟<>,然后将实例化的 类型放在<>中即可,类模板名字不是真正的类,而实例化的结果才是真正的类。
这里和函数模板同理,其实是两个类型,并不是一个类型。 四.?模板分离编译1.?什么是分离编译一个程序(项目)由若干个源文件共同实现,而每个源文件单独编译生成目标文件,最后将所有 目标文件链接起来形成单一的可执行文件的过程称为分离编译模式。 2. 模板的分离编译(1)需要注意函数模板和类模板的分离后的声明和定义方式: 函数模板声明:
函数模板的定义:
类模板声明:
类模板的定义:
(2)分离编译其实也是会出现问题的: 以模板函数为例: 假如有以下场景,模板的声明与定义分离开,在头文件中进行声明,源文件中完成定义:
当按上面的步骤进行编译运行便会出现以下问题: 直接出现链接错误,什么情况? 根据C/C++程序运行之前需要经历以下步骤: 预处理--->编译--->汇编--->链接 链接的任务是将多个.o文件合并成一个,并处理没有解决的地址问题,即合并符号表。也就是说这里出现链接错误其实是符号表合并失败了,为什么? template.h在template.cpp被包含了,预编译阶段会进行展开,也就是说,template.cpp在编译阶段时需要编译template.cpp并生成符号表,但是,由于template.cpp中,编译器并没有看到对Add模板函数的实例化,因此不会生成具体的Add函数,因此没有函数地址,template.cpp中符号表就是空的了。 template.h在test.cpp中被包含了,预编译阶段会进行展开,也就是说,test.cpp在编译阶段需要编译test.cpp并生成符号表,在test.o中调用了Add<int>和Add<double>,编译器在链接阶段会去找该函数的地址,但是这两个函数由于在template.cpp时没有实例化,就没有生成函数地址,template.cpp中的符号表里就没有这两个函数的地址,而test.cpp的符号表和template.cpp符号表合并时找不到该函数地址,就报链接时错误。 事实上,类模板也是这类问题,以下是类模板的情况: 3. 解决方法
如下分别是第一种和第二种解决函数模板的执行结果: 以下分别是第一种和第二种解决类模板问题的执行结果: 我们会发现:虽然第二种可以,但是很麻烦,每实例化一个需要自己在template.cpp中显示实例化,太麻烦了,因此采用第一种方法是最佳的处理方法。 由此,得出一个结论: 模板不支持声明和定义分离到xxx.h和xxx.cpp中,一般放一个文件中。为了方便辨别有些地方会命名成xxx.hpp。 |
|
C++知识库 最新文章 |
【C++】友元、嵌套类、异常、RTTI、类型转换 |
通讯录的思路与实现(C语言) |
C++PrimerPlus 第七章 函数-C++的编程模块( |
Problem C: 算法9-9~9-12:平衡二叉树的基本 |
MSVC C++ UTF-8编程 |
C++进阶 多态原理 |
简单string类c++实现 |
我的年度总结 |
【C语言】以深厚地基筑伟岸高楼-基础篇(六 |
c语言常见错误合集 |
|
上一篇文章 下一篇文章 查看所有文章 |
|
开发:
C++知识库
Java知识库
JavaScript
Python
PHP知识库
人工智能
区块链
大数据
移动开发
嵌入式
开发工具
数据结构与算法
开发测试
游戏开发
网络协议
系统运维
教程: HTML教程 CSS教程 JavaScript教程 Go语言教程 JQuery教程 VUE教程 VUE3教程 Bootstrap教程 SQL数据库教程 C语言教程 C++教程 Java教程 Python教程 Python3教程 C#教程 数码: 电脑 笔记本 显卡 显示器 固态硬盘 硬盘 耳机 手机 iphone vivo oppo 小米 华为 单反 装机 图拉丁 |
360图书馆 购物 三丰科技 阅读网 日历 万年历 2024年11日历 | -2024/11/23 17:05:46- |
|
网站联系: qq:121756557 email:121756557@qq.com IT数码 |