C++基础知识:泛型编程
1.泛型编程的概念
---不考虑具体数据类型的编程模式
Swap 泛型写法中的 T 不是一个具体的数据类型,而是泛指任意的数据类型.
2.函数模板
- 函数模板其实是一个具有相同行为的函数家族,可用不同类型进行调用
- 函数模板可以根据类型实参对函数进行推导调用
- 函数模板可以显示的指定类型参数
- 函数模板可以被重载
①函数模板的语法规则
―template 关键字用于声明开始进行泛型编程
―typename 关键字用于声明泛指类型

②函数模板的应用
―自动类型推导调用
―具体类型显示调用
3.函数模板的深入理解
― 编译器并不是把函数模板处理成能够处理任意类型的函数
― 编译器从函数模板通过具体类型产生不同的函数
― 编译器会对函数模板进行两次编译
- 在声明的地方对模板代码本身进行编译
- 在调用的地方对参数替换后的代码进行编译
4.函数模板与重载
函数模板可以像普通函数一样被重载
C++ 编译器优先考虑普通函数
如果函数模板可以产生一个更好的匹配 , 那么选择模板
可以通过空模板实参列表的语法限定编译器只通过模板匹配

注意:

5.多参数函数模板
函数模板可以定义任意多个不同的类型参数
当声明的类型参数为返回值类型时 , 无法进行自动类型推导。

不完美解决方案:
将返回类型参数声明到第一个参数位置 , 调用时只需显示声明返回类型参数即可。

6.类模板
一些类主要用于存储和组织数据元素
―如 : 数组类 , 链表类,链表类 , Stack类,Queue类等等
C++中可以将模板的思想应用于类中,使得类的可以不关注具体所操作的数据类型,而只关注类所需要实现的功能 :

声明的泛指类型 T 可用于声明成员变量和成员函数
编译器对类模板的处理方式和函数模板相同
― 编译器从类模板通过具体类型产生不同的类
― 编译器在声明的地方对类模板代码本身进行编译
― 编译器在使用的地方对参数替换后的代码进行编译

由于类模板的编译机制不同 , 所以不能像普通类一样分开实现后在使用时只包含头文件,在工程实践上 , 一般会把类模板的定义直接放到头文件中!!
只有被调用的类模板成员函数才会被编译器生成可执行代码!!!

类模板可以被特化:用 template<>声明一个类时, 表示这是一个特化类!
特化类模板的意义:
当类模板在处理某种特定类型有缺陷时 , 可以通过类模板的特化来克服处理这种特定类型带来的不足
注意:编译器优先选择特化类生成对象!!

类模板的局部特化:可以指定类模板的特定实现 , 并要求某些类型参数仍然必须得模板的用户指定

为什么需要特化,而不重新定义新类 ?
― 特化和重新定义新类看上去没有本质区别, 但是如果定义新类, 那么将变成一个类模板和一个新类,使用的时候需要考虑究竟是用类模板还是用新类
― 而特化可以统一的方式使用类模板和特化类 , 编译器自动优先选择特化类
非类型模板参数的限制:
-函数模板和类模板的模板参数可以是普通数值
-变量不能作为模板参数
-浮点数和类对象不能作为模板参数
-全局指针不能作为模板参数
-编译器的推导过程是在编译阶段完成的, 因此,编译器的推导必须依赖于特化类,否则推导过程无法结束。


怎么判断一个变量是否为指针???(模板与可变参数函数)
-C++中仍然支持C语言中的可变参数函数
-C++编译器的匹配调用优先级
重载函数
函数模板
可变参数函数

工程问题:内存泄露,内存多次释放,使用越界...
①内存越界的问题常发生于数组的使用中
―解决方案 : 数组类
―工程中, 在非特殊情况下 , 要求开发者使用预先编写的数组类对象代替C 语言中的原生数组
②内存泄漏和内存多次释放常发生于指针的使用过程中
―解决方案: 智能指针
―工程中 , 要求开发者使用预先编写的智能指针类对象代替 C 语言中的原生指针
工程中的智能指针是一个类模板:
―通过构造函数接管申请的堆内存
―通过析构函数确保堆内存被及时释放
―通过重载指针运算符* 和 - > 模拟指针的行为
―通过重载比较运算符 == 和 != 模拟指针的比较
7.智能指针的深入理解:
STL常用的7种智能指针:std::auto_ptr、boost::scoped_ptr、boost::shared_ptr、boost::scoped_array、
boost::shared_array、boost::weak_ptr、boost:: intrusive_ptr
①std::auto_ptr:
(1) 尽量不要使用“operator=”。如果使用了,请不要再使用先前对象。
(2) 记住 release() 函数不会释放对象,仅仅归还所有权。
(3) std::auto_ptr 最好不要当成参数传递(读者可以自行写代码确定为什么不能)。
(4) 由于 std::auto_ptr 的“operator=”问题,有其管理的对象不能放入 std::vector 等容器中。
②boost::scoped_ptr
(1)scoped_ptr 没有 release 函数
(2)没有重载 operator=,不会导致所有权转移,但无法赋值,拷贝智能指针。
③boost::shared_ptr
(1)专门用于共享所有权,内部使用引用计数use_count() ,因此可以支持复制、参数传递等,也是用于管理单个堆内存对象的。
(2)同样没有release() 函数。
④boost::scoped_array
(1)用于管理动态数组
(2) boost::scoped_array<Simple> my_memory(new Simple[2]); // 使用内存数组来初始化
(3)scoped_ptr 没有重载 operator*
(4)没有重载 operator=
⑤boost::shared_array
内部使用了引用计数,可以复制,通过参数来传递。
⑥boost::weak_ptr
是专门为 boost::shared_ptr 而准备的,boost::weak_ptr 只对 boost::shared_ptr 进行引用,而不改变其引用计数,
当被观察的 boost::shared_ptr 失效后,相应的 boost::weak_ptr 也相应失效
⑦boost::intrusive_ptr
这是一种插入式的智能指针,内部不含有引用计数,需要程序员自己加入引用计数。
智能指针总结:
1、在可以使用 boost 库的场合下,拒绝使用 std::auto_ptr,因为其不仅不符合 C++ 编程思想,而且极容易出错[2]。
2、在确定对象无需共享的情况下,使用 boost::scoped_ptr(当然动态数组使用 boost::scoped_array)。
3、在对象需要共享的情况下,使用 boost::shared_ptr(当然动态数组使用 boost::shared_array)。
4、在需要访问 boost::shared_ptr 对象,而又不想改变其引用计数的情况下,使用 boost::weak_ptr,一般常用于软件框架设计中。
5、最后一点,也是要求最苛刻一点:在你的代码中,不要出现 delete 关键字(或 C 语言的 free 函数),因为可以用智能指针去管理。
C++基础知识:泛型编程的更多相关文章
- .NET面试题系列[1] - .NET框架基础知识(1)
很明显,CLS是CTS的一个子集,而且是最小的子集. - 张子阳 .NET框架基础知识(1) 参考资料: http://www.tracefact.net/CLR-and-Framework/DotN ...
- RabbitMQ基础知识
RabbitMQ基础知识 一.背景 RabbitMQ是一个由erlang开发的AMQP(Advanced Message Queue )的开源实现.AMQP 的出现其实也是应了广大人民群众的需求,虽然 ...
- Java基础知识(壹)
写在前面的话 这篇博客,是很早之前自己的学习Java基础知识的,所记录的内容,仅仅是当时学习的一个总结随笔.现在分享出来,希望能帮助大家,如有不足的,希望大家支出. 后续会继续分享基础知识手记.希望能 ...
- selenium自动化基础知识
什么是自动化测试? 自动化测试分为:功能自动化和性能自动化 功能自动化即使用计算机通过编码的方式来替代手工测试,完成一些重复性比较高的测试,解放测试人员的测试压力.同时,如果系统有不份模块更改后,只要 ...
- [SQL] SQL 基础知识梳理(一)- 数据库与 SQL
SQL 基础知识梳理(一)- 数据库与 SQL [博主]反骨仔 [原文地址]http://www.cnblogs.com/liqingwen/p/5902856.html 目录 What's 数据库 ...
- [SQL] SQL 基础知识梳理(二) - 查询基础
SQL 基础知识梳理(二) - 查询基础 [博主]反骨仔 [原文]http://www.cnblogs.com/liqingwen/p/5904824.html 序 这是<SQL 基础知识梳理( ...
- [SQL] SQL 基础知识梳理(三) - 聚合和排序
SQL 基础知识梳理(三) - 聚合和排序 [博主]反骨仔 [原文]http://www.cnblogs.com/liqingwen/p/5926689.html 序 这是<SQL 基础知识梳理 ...
- [SQL] SQL 基础知识梳理(四) - 数据更新
SQL 基础知识梳理(四) - 数据更新 [博主]反骨仔 [原文]http://www.cnblogs.com/liqingwen/p/5929786.html 序 这是<SQL 基础知识梳理( ...
- [SQL] SQL 基础知识梳理(五) - 复杂查询
SQL 基础知识梳理(五) - 复杂查询 [博主]反骨仔 [原文]http://www.cnblogs.com/liqingwen/p/5939796.html 序 这是<SQL 基础知识梳理( ...
- APP测试入门篇之APP基础知识(001)
前言 最近两月比较多的事情混杂在一起,静不下心来写点东西,月初想发表一遍接口测试的总结,或者APP测试相关的内容,一晃就月底了,总结提炼一时半会也整不完.放几个早年总结内部培训PPT出来 ...
随机推荐
- (转)C# 的 String.CompareTo、 Equals和==的比较
String.CompareTo 语法 public int CompareTo( string strB) 返回值 小于 0,实例小于参数 strB: 0,实例等于参数 strB: 大于 0, ...
- LeetCode--404--左叶子之和
问题描述: 计算给定二叉树的所有左叶子之和. 示例: 3 / \ 9 20 / \ 15 7 在这个二叉树中,有两个左叶子,分别是 9 和 15,所以返回 24 方法:recursive class ...
- flex自定义preloader预加载进度条
flex默认的preloader已经很不错了,可是有时候还是需要自定义的. 需要在要出现自定义预加载的程序的<mx:Application>标签里加入preloader="& ...
- ubuntu vi配置
1.先卸载tiny版本vi 输入命令:sudo apt-get remove vim-common 2.然后再输入命令: sudo apt-get install vim sudo vim /et ...
- Spring Batch @EnableBatchIntegration 注解
设置一个远程分块任务需要定义一系列的 beans: 一个连接工程来从消息中间件中获得连接,消息中间件包括有(JMS,AMQP 和其他) 一个 MessagingTemplate 来从主向从发送消息, ...
- 【洛谷p1926】小书童——蚂蚁大战
f(今天开学第一天) 小书童——蚂蚁大战[传送门] 洛谷算法标签: 这个题要用排序是真的很神奇: 首先我们来理解一下题意:首先蚂蚁们按血量接受打击[魔鬼操作],血量最少的蚂蚁要走到最前面,所以我们可以 ...
- mac下 配置homebrew 和java home
1.terminal下输入 /usr/bin/ruby -e "$(curl -fsSL https://raw.githubusercontent.com/Homebrew/insta ...
- 直播 APP 的直播实现流程
直播平台搭建所涉及的事项非常的广泛, 不仅需要直播源码. 直播系统开发. 后台服务 器.专门的运维人员等, 还需要技术团队切实的把控.下面, 小编就给大家确切的说下直播 平台搭建需要用到哪些步骤. 1 ...
- 『流畅的Python』第9章笔记_对象
一.Python风格 以一个二元素向量对象为例 import math from array import array class Vector2d: typecode = 'd' def __ini ...
- Windows下Python3.6安装第三方模块
一 安装pip 一般需要用pip进行安装,不过我安装p3.6的时候pip已经有了. 如果没有的话,可以用在以下http://www.lfd.uci.edu/~gohlke/pythonlibs/#pi ...