Effective C++学习笔记(7)

目录

  • 条款41:了解隐式接口和编译多态
  • 条款42:了解typename的双重意义
  • 条款43:学习处理模板化基类内的名称
  • 条款44:将与参数无关的代码抽离templates
  • 条款45:运用成员函数模板接受所有兼容类型
  • 条款46:需要类型转换时请为模板定义非成员函数
  • 条款47:请使用traits classes表现类型信息
  • 条款48:认识模板元编程

条款41:了解隐式接口和编译多态

  • 显示接口:在源码中可以找到明确可见的函数接口。
    在这里插入图片描述

- 隐式接口:不是基于函数签名式,而是有效表达式组成的接口。如下图,函数接口最终实例化成什么函数和模板参数T有关,在代码编译之前是不确定的。
在这里插入图片描述

  • 运行期多态:在运行期虚函数指针根据指向对象确定哪一个虚函数该被绑定调用。
  • 编译期多态:在编译期以不同的模板参数具现化会导致调用不同的函数。
  • 对classes而言接口是显式的(explicit),以函数签名为中心。多态则是通过 virtual函数发生于运行期
  • 对template参数而言,接口是隐式的(implicit),奠基于有效表达式。多态则是通过template具现化和函数重载解析(function overloading resolution)发生于编译期

条款42:了解typename的双重意义

  • 当声明template类型参数时,class和typename意义完全相同。建议使用typename
  • template内出现的名称如果相依于某个template参数,称之为从属名称(dependent names)。如果从属名称在 class内呈嵌套状,我们称它为嵌套从属名称(nested dependent name)。
  • 当嵌套从属名称表示一个类型时,需要加上typename前缀,表示是一个类型,也叫做嵌套从属类型名称;如果不加typename前缀,默认这个嵌套从属名称是一个非类型(例如某个类的静态成员变量C::value)。
    在这里插入图片描述
    在这里插入图片描述
  • “typename必须作为嵌套从属类型名称的前缀词”这一规则的例外是,**typename不可以出现在base classes list内的嵌套从属类型名称之前,也不可在member initialization list(成员初值列)中作为base class修饰符。**例如:
    在这里插入图片描述
  • 对于冗长的嵌套从属类型名称可用typedef简化
    在这里插入图片描述

条款43:学习处理模板化基类内的名称

  • C++拒绝这个调用的原因:它知道base class templates有可能被特化,而那个特化版本可能不提供和一般性 template相同的接口。因此它往往拒绝在 templatized base classes(模板化基类,本例的MsgSender)内寻找继承而来的名称(本例的 sendClear)。实例化前编译器不进入base class作用域内查找。就某种意义而言,当我们从Object Oriented C++跨进Template C++,继承就不像以前那般畅行无阻了。
    在这里插入图片描述

  • 解决方法统一思路:对编译器承诺“base class template的任何特化版本都将支持其一般(泛化)版本所提供的接口”。

  • 解决方法1:在base class 函数调用动作之前加上“this->”
    在这里插入图片描述

  • 解决方法2:使用using声明式提前声明模板基类函数
    在这里插入图片描述

  • 解决方法3(不推荐):明确指出调用的函数位于模板基类里。若调用的是virtual函数,这种明确修饰会关闭“virtual绑定行为”(只会调用基类的虚函数,而不会调用继承类中对应重写的虚函数):
    在这里插入图片描述

  • 编译器的诊断时间可能发生在早期(当解析derived class template 的定义式时),也可能发生在晚期(当那些templates被特定之template 实参具现化时)。C++的政策是宁愿较早诊断,这就是为什么“当base classes 从templates中被具现化时”
    它假设它对那些baseclasses的内容毫无所悉的缘故。

条款44:将与参数无关的代码抽离templates

  • 模板代码膨胀:其二进制码带着重复(或几乎重复)的代码、数据,或两者。其结果有可能源码看起来合身而整齐,但目标码(object code) 却不是那么回事。
  • Templates生成多个classes和多个函数,所以任何template代码都不该与某个造成膨胀的template参数产生相依关系。
  • 非类型模板参数(non- type template parameters) 而造成的代码膨胀,往往可消除,做法是以函数参数或class成员变量替换template参数
  • 类型参数(type parameters)而造成的代码膨胀,往往可降低,做法是让带有完全相同二进制表述( binary representations)的具现类型( instantiation types)共享实现码
  • 有时愈是尝试精密的做法,事情变得愈是复杂。从某个角度看,一点点代码重复反倒看起来有点幸运了。需要在具体不同平台进行衡量。

条款45:运用成员函数模板接受所有兼容类型

  • 以智能指针是“行为像指针”的对象,讨论如何实现成员函数模板用于接受所有兼容类型,泛化智能指针操作类似指针操作。
  • 通过成员函数模板建立一个泛化的copy构造函数,使得该拷贝构造函数可以支持智能指针隐式转换。这个行为只有当“存在某个隐式转换可将-一个U指针转为-一个T指针”时才能通过编译,而那正是我们想要的。这个构造函数只在其所获得的实参隶属适当(兼容)类型时才通过编译:
    在这里插入图片描述
  • 通过成员函数模板建立一个泛化的赋值操作“=”函数。下图所有构造函数都是explicit, 惟有“泛化copy构造函数”除外。那意味从某个shared_ ptr 类型隐式转换至另一个shared ptr 类型是被允许的,但从某个内置指针或从其他智能指针类型进行隐式转换则不被认可(如果是显式转换如cast强制转型动作倒是可以)。
    在这里插入图片描述
  • member templates 并不改变语言规则,而语言规则说,如果程序需要一个copy构造函数,你却没有声明它,编译器会为你暗自生成一个。 在class内声明泛化copy构造函数(是个member template)并不会阻止编译器生成它们自己的copy构造函数(一个non-template),所以如果你想要控制copy构造的方方面面,你必须同时声明泛化copy构造函数和“正常的”copy构造函数。相同规则也适用于赋值( assignment)操作
    在这里插入图片描述

条款46:需要类型转换时请为模板定义非成员函数

  • 模板中,根据实参推导模板参数类型时不支持隐式类型转换推导。如果一个模板类中,模板内的函数需要参数类型转换,成员函数无法做到。函数参数隐式类型转换之前需要确定该函数存在,而实例化之前成员函数并不存在。
  • 可在模板类内中采用friend函数声明和定义,使其声明跟随模板类一起实例化,之后再调用的时候就可以自动找到该函数的声明,进行隐式类型转换(下图中可在*重载中输入int类型数据,使其隐式调用Rational的int类型构造函数,隐式转换为Rational<int>)。
    在这里插入图片描述
  • 由于定义于class内中的函数暗自成为inline,可采用class内中friend函数啥也不干,只调用一个外部辅助函数即可,减小inline声明所带来的冲击
    在这里插入图片描述

条款47:请使用traits classes表现类型信息

  • STL中迭代器可分为五类,继承关系如下图:
    (1). Input 迭代器,只能一步一步向前移动,只能读取内容,且仅读取一次。
    (2). Output 迭代器,只能一步一步向前移动,只能写入内容,且仅写入一次。
    (3). Forward 迭代器,只能一步一步向前移动,可读可写多次。
    (4). Bidirectianol 迭代器,只能一步一步向前或向后移动,可读可写多次。
    (5). Random Access 迭代器,可以在常量时间以任意步数向前或向后移动,可读可写多次。

在这里插入图片描述

  • Traits是一种技术,也是一个C++程序员共同遵守的协议。它对内置类型和用户自定义类型的表现必须一样好

  • Traits设计实现流程(例子是实现advance模板函数,可以接受各种类型的迭代器进行移动):
    -(1)确认若干你希望将来可取得的类型信息;
    -(2)为该信息选一个名称;
    在这里插入图片描述
    -(3)提供一个template和一组特例化版本( 例特例化内置指针类型):
    在这里插入图片描述
    在这里插入图片描述

  • Traits classes使得“类型相关信息”在编译期可用。它们以templates和“templates特化”完成实现。整合重载技术( overloading) 后,traitsclasses有可能在编译期对类型执行if…else测试。(上述advance中有类型条件判单,是在运行期执行,可采用重载技术使其在编译期进行,仅在advance函数中调用重载函数即可,如下图)。
    在这里插入图片描述

在这里插入图片描述

  • 如何使用一个traits class:
    (1)建立一组重载函数 (身份像劳工)或函数模板(例如doAdvance) ,彼此间的差异只在于各自的traits参数。令每个函数实现码与其接受之traits信息相应和。.
    (2)建立一个控制函数 (身份像工头)或函数模板(例如advance) ,它调用上述那些“劳工函数”并传递traits class所提供的信息。

条款48:认识模板元编程

  • Template metaprogramming (TMP,模板元编程)可将工作由运行期移往编译期,因而得以实现早期错误侦测和更高的执行效率。
  • TMP可被用来生成“基于政策选择组合”的客户定制代码,也可用来避免生成对某些特殊类型并不适合的代码。
  • 由于template metaprograms执行于C++编译期,因此可将工作从运行期转移到编译期。这导致的一个结果是,某些错误原本通常在运行期才能侦测到,现在可在编译期找出来。另一一个结果是,使用TMP的C++程序可能在每一方面都更高效:较小的可执行文件、较短的运行期、较少的内存需求。然而将工作从运行期移转至编译期的另一个结果是,编译时间变长了
  • TMP中if…else…可通过模板函数重载实现;TMP循环结构可使用递归;TMP递归涉及递归模板具现化,如下图计算阶乘:
    在这里插入图片描述

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/news/39492.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

avue多选列表根据后端返回的某个值去判断是否选中;avue-curd多选回显

效果如上&#xff1a; getSiteList().then(res > {//列表数据this.siteData res.data.datathis.$nextTick(()>{this.siteData.forEach(item>{//业务条件if(item.configid&&item.configid!0&&item.configid>0){//符合条件时调用选中的方法this.$…

JAVASE---数组的定义与使用

数组的基本概念 什么是数组 数组是具有相同类型元素的集合&#xff0c;在内存中连续存储。 1. 数组中存放的元素其类型相同 2. 数组的空间是连在一起的 3. 每个空间有自己的编号&#xff0c;起始位置的编号为0&#xff0c;即数组的下标 数组的创建及初始化 数组的创建 T[…

Java SpringBoot Vue智能停车系统

基础环境 JDK1.8、Maven、Mysql、IntelliJ IDEA 内置功能 系统管理&#xff1a;角色管理、接口管理、系统菜单、全局配置 账号管理&#xff1a;用户管理、合作单位 系统监控&#xff1a;监控大屏、日志监控 财务管理&#xff1a;订单列表 停车记录&#xff1a;停车记录 车辆管…

Labview选项卡之实现被选择选项卡工作

文章目录 前言一、使用选项卡二、实现被选择选项卡工作1、需求2、分析3、实现①、前面板②、程序框图 三、效果展示四、源码自取 前言 有些时候&#xff0c;我们做界面&#xff0c;需要好多个界面切换。如果是同一个 VI 里界面切换&#xff0c;一般都是选项卡了。切换不同选项…

使用phpstorm开发调试thinkphp

1.环境准备 1.开发工具下载&#xff1a;PhpStorm: PHP IDE and Code Editor from JetBrains 2.PHP下载&#xff1a;PHP: Downloads 3. PHP扩展&#xff1a;PECL :: Package search 4.用与调试的xdebug模块&#xff1a; Xdebug: Downloads xdebug模块&#xff0c;如果是php8以…

23.8.16日总结

原先写的评论是每级评论用缩进来区分&#xff0c;所以最多设置的是九级评论&#xff0c;修改了排版和格式&#xff1a; 还有管理员页面&#xff0c;查看文章时可以进行点赞&#xff0c;收藏的操作&#xff0c;现在进行了修改&#xff0c;将相关操作隐藏。 还有点击查看未发布…

14-矩阵相乘及其运算法则

矩阵与向量的乘法 在这一篇文章中我们就将基于上一篇重新审视矩阵的这个视点来理解矩阵的乘法&#xff0c;那么在这一篇&#xff0c;我们主要来看一下矩阵和向量的乘法。这里这个线性方程组是上一小节给大家举的模拟的一个非常简单的小型经济系统的例子&#xff0c;我们可以把…

文件的导入与导出

文章目录 一、需求二、分析1. Excel 表格数据导出2. Excel 表格数据导入一、需求 在我们日常开发中,会有文件的导入导出的需求,如何在 vue 项目中写导入导出功能呢 二、分析 以 Excel 表格数据导出为例 1. Excel 表格数据导出 调用接口将返回的数据进行 Blob 转换,附: 接…

logstash日志换行处理小解

logstash主用于日志实时数据收集、解析&#xff0c;并将数据转发的工具&#xff0c;内置的功能也相当强大。但&#xff0c;同时意味着&#xff0c;他可能接收到各种情况的数据。 此处&#xff0c;我们主要讲解我实际使用中&#xff0c;碰到的一个小问题&#xff0c;换行(\n)。…

FPGA应用学习笔记--时钟域的控制 亚稳态的解决

时钟域就是同一个时钟的区域&#xff0c;体现在laways语句边缘触发语句中&#xff0c;设计规模增大就会导致时钟不同步&#xff0c;有时差&#xff0c;就要设计多时钟域。 会经过与门的延时产生的新时钟域&#xff0c;这种其实不推荐使用&#xff0c;但在ascl里面很常见 在处理…

八大排序超详解(动图+源码)

&#x1f493;博主个人主页:不是笨小孩&#x1f440; ⏩专栏分类:数据结构与算法&#x1f440; 刷题专栏&#x1f440; C语言&#x1f440; &#x1f69a;代码仓库:笨小孩的代码库&#x1f440; ⏩社区&#xff1a;不是笨小孩&#x1f440; &#x1f339;欢迎大家三连关注&…

虚幻5中Lumen提供哪些功能以及如何工作的

虚幻引擎 5 中的 Lumen 是一个完全动态的全局照明和反射系统。它可以在虚幻引擎 5 中使用&#xff0c;因此创作者无需自行设置。它是为下一代控制台和建筑可视化等高端可视化而设计的。那么它提供了哪些功能以及如何工作&#xff1f; 全局照明 当光离开光源时&#xff0c;它会…

负载均衡搭建

LVS-DR部署 [客户端] node1 192.168.157.148 [lvs] node2 192.168.157.142 [web服务器] node3 192.168.157.145 node4 192.168.157.146&#xff08;1&#xff09;[lvs] yum install -y ipvsadm.x86_64 配置LVS负载均衡服务 &#xff08;1&#xff09;手动添加LVS转发1&#xff…

系统架构设计专业技能 · 软件工程之软件测试与维护(六)【系统架构设计师】

系列文章目录 系统架构设计专业技能 网络规划与设计&#xff08;三&#xff09;【系统架构设计师】 系统架构设计专业技能 系统安全分析与设计&#xff08;四&#xff09;【系统架构设计师】 系统架构设计高级技能 软件架构设计&#xff08;一&#xff09;【系统架构设计师…

MAVEN利器:一文带你了解MAVEN以及如何配置

前言&#xff1a; 强大的构建工具——Maven。作为Java生态系统中的重要组成部分&#xff0c;Maven为开发人员提供了一种简单而高效的方式来构建、管理和发布Java项目。无论是小型项目还是大型企业级应用&#xff0c;Maven都能帮助开发人员轻松处理依赖管理、编译、测试和部署等…

YOLOV7改进:加入RCS-OSA模块,提升检测速度

1.该文章属于YOLOV5/YOLOV7/YOLOV8改进专栏,包含大量的改进方式,主要以2023年的最新文章和2022年的文章提出改进方式。 2.提供更加详细的改进方法,如将注意力机制添加到网络的不同位置,便于做实验,也可以当做论文的创新点。 2.涨点效果:RCS-OSA模块更加轻量化,有效提升检…

Spring Boot业务代码中使用@Transactional事务失效踩坑点总结

1.概述 接着之前我们对Spring AOP以及基于AOP实现事务控制的上文&#xff0c;今天我们来看看平时在项目业务开发中使用声明式事务Transactional的失效场景&#xff0c;并分析其失效原因&#xff0c;从而帮助开发人员尽量避免踩坑。 我们知道 Spring 声明式事务功能提供了极其…

Kafka 01——Kafka的安装及简单入门使用

Kafka 01——Kafka的安装及简单入门使用 1. 下载安装1.1 JDK的安装1.2 Zookeeper的安装1.2.1 关于Zookeeper版本的选择1.2.2 下载、安装Zookeeper 1.3 kafka的安装1.3.1 下载1.3.2 解压1.3.3 修改配置文件 2. 启动 kafka2.1 Kafka启动2.2 启动 kafka 遇到的问题2.2.1 问题12.2.…

Python爱心光波

文章目录 前言Turtle入门简单案例入门函数 爱心光波程序设计程序分析 尾声 前言 七夕要来啦&#xff0c;博主在闲暇之余创作了一个爱心光波&#xff0c;感兴趣的小伙伴们快来看看吧&#xff01; Turtle入门 Turtle 是一个简单而直观的绘图工具&#xff0c;它可以帮助你通过简…

面试笔记:Android 架构岗,一次4小时4面的体验

作者&#xff1a;橘子树 此次面试一共4面4小时&#xff0c;中间只有几分钟间隔。对持续的面试状态考验还是蛮大的。 关于面试的心态&#xff0c;保持悲观的乐观主义心态比较好。面前做面试准备时保持悲观&#xff0c;尽可能的做足准备。面后积极做复盘&#xff0c;乐观的接受最…