C++ 侯捷 程序设计(Ⅱ)兼谈对象模型 笔记

Conversion function 转换函数

侯捷老师使用分数 Fraction举例,分数理应可以被看作是小数

提供了Fraction类对象一个转换为double的方法,当碰到需要转换为double的情况下,会调用该方法。

黄色的就是转换函数,没有return type,返回类型就是名称double这一类型。

分析  double d = 4 + f;

编译器会找是否有全局函数 operator + ,第一个参数是整数或浮点数(整数是浮点数),第二个参数是Fraction,若有这么个函数,就会走得通。

但示例代码中没有这么一个全局函数,故会去找有没有将fraction转换为double的转换函数。

non-explicit / explicit  -one-argument-ctor

Fraction f(3,5);
Fraction d2 = f + 4;

写的operator+ 代码作用左边f,传的参数是右边的4,但4是int型,而参数要求类型是Fraction,因为有绿色代码,会调用 non-explicit ctor 将4 转换为 Fraction (4,1), 然后调用operator+。可以看出这个non-explicit ctor可以把别的类型转换为该类型,与上一节转换函数把该类型转换为其它类型不同。 

当黄绿色代码并存时,

绿色可以把4转换为fraction,operator+也有,看起来可以执行d2 = f + 4

黄色会把f转换为double 0.6,相加得到4.6,4.6再转换为fraction,这也可以走得通。

但当多余一条路线可走时,编译器就不知道怎么走了,就会出现歧义ambiguous,发生报错。

(conversion function中的图不会报错,是因为做的事情并没有出现二义现象)

转换函数,ctor,operator重载,都会影响

explict(基本只有构造函数会用到,模板很细微的地方也会用到)

加上explicit后,就不会自动的将4转换为Fraction

Fraction f(3,5);
Fraction d2 = f + 4; //[error] conversion from 'double' to 'Fraction' requested

则 d2 = f + 4会报错,因为operator+要求右边是Fraction参数

pointer-like classes

关于智能指针

指针允许的动作,该类都要允许。

sp->method(),智能指针要满足这一动作,所以重载了操作符,返回了px,但sp-> 会被转换为px,这还差一个->符号呢。

->符号有个特殊行为,作用下去得到的结果会继续用->符号作用下去,也因此可行。

关于迭代器

迭代器也可以看作是一种智能指针,但他除了要处理*,->等符号,还要去处理++,--等运算符号

function-like classes

所谓仿函数

对()重载,就能做到仿函数,所做出来的对象可以接受()。

实际上仿函数都继承了某一类

 

仿函数继承的类(详细作用在标准库课程中讲)

namespace经验谈

取一个namespace命名空间,用来将自己定义的变量等包起来,以免与其它人写的变量名起到冲突。

Template 模板

class template 类模板

先用T来泛指类型,以后再来指定类型。

member template 成员模板

在模板里头,自己又是模板。可以认为外头模板的T1,T2可以变化,里头的U1,U2又可以变化  

图例可以拷贝,反之不可以,如图的pair的构造函数可以看出,允许使用U1,U2类型的pair来进行构造,但是要满足p的first(U1),second(U2)要可以当作T1,T2.

specialization 模板特化

作为一个设计者,可能面对某些独特的类型,要做独特的设计。

如图上方的框内是泛化,指定任意类型都会使用上框中的代码。

但如果指定如下框中的char,int,long的类型,则会使用下框代码

写出代码

cout<< hash<long>()(1000);

hash<long>()表示是个临时的变量,因为是long类型,会用特化的代码,接着就是调用重载的()

partial specialization 模板偏特化 -- 个数的偏

2个typename,当T是bool时,进行特化,只有一个T进行特化,个数的偏

partial specialization 模板偏特化 -- 范围的偏

特化指针类型,范围的偏

template template parameter 模板模板参数

尖括号内 typename和class共通。也可以写template<class T>。

list确实是模板模板参数,Container会把T,也就是string放进去,这样list<string>好像也没问题,

但是实际上容器有第二模板参数,甚至有三,平时不写是因为有默认值。在这里虽然有默认值,但是仍然不行,想要解决可以用Lst这样来实现(C++2.0中的语法)。

SmartPtr有的只接受一个模板参数,因此有的可以,打×不是参数原因,是指针特性原因。

Sequence也是个模板(deque<T>),为什么不是模板模板参数呢。

看用法中,第二个用法stack<int,list<int>> s2,第二个参数不再是模板了。

variadic templates(since C++11)数量不定的模板参数

...不是省略,是语法一部分

auto(since C++11)

auto要让编译器可以推理

ranged-base for(since C++11)

auto elem 是值传递,会把值copy到elem中,如果想要更改vec中的内容,用引用。

Reference

编译器对待r,当作指针实现,真实大小为指针大小,但逻辑上r就是x,所以sizeof(r) == sizeof(x)。(编译器制造的假象)

r不能重新代表其它物体,它就是x

const函数签名的一部分

Object Model

前情提要C++ 组合 委托 继承 组合使用-CSDN博客

vptr和vtbl(虚指针和虚表)

图中可以看出,每个对象中存在一个虚指针,指向自己类的虚表(类对象共用一个虚表)

虚表中存放各虚函数的地址

子类同名虚函数会覆盖父类虚函数,覆盖虚表位置与父类相同

虚函数表的指针存在于对象实例中最前面的位置

通过指针调用虚函数,编译器不能使用静态绑定(call(函数地址)),而是动态绑定,动过指针p找到vptr,再找到虚表中的对应函数地址。

如图,父类指针指向子类对象,调用同名虚函数draw(),会调用子类的虚函数draw()

符合动态绑定的条件

1.通过指针调用

2.指针向上转型(上行转换,保证安全)

3.调用虚函数

关于this

通过对象调用函数,对象的地址就是this

子类对象调用父类函数,父类中OnFileOpen函数执行到Serialize()时,会调用子类的Serialize函数

这是因为动态绑定,myDoc.OnFileOpen(),是子类myDoc调用,因此this是&myDoc,编译器会把所有调用函数的动作视为类似this->Serialize()的动作。this是指针,且调用OnFileOpen父类的函数符合向上转型,调用Serialize是虚函数,因此满足动态绑定的三个条件

关于Dynamic Binding 动态绑定

如图a.vfunc1(),是通过对象来调用函数,而不是指针,因此是静态绑定。

从call往前的几行汇编 用C表现是(*(p->vptr)[n])(p);

即通过p指针找到vptr,再找到虚表中函数对应位置进行调用,传进去的p即为this pointer。

补充

const

const修饰函数一般是修饰成员函数

成员函数的const 和 non-const 版本同时存在

const object 只能调用const版本

non-const object 只能调用non-const版本

不同时存在时,non-const object可以调用const版本,但const object 只能调用 const版本

const是签名的一部分

如 string s = "hello world"

s[0] = 'p'; //更改了(s为非常量对象)

此时会调用返回是 reference的函数

重载 new  delete

全局重载

类内重载成员函数

重载示例

::new Foo这样的用法会使用全局的new,绕过自己的重载

new[] 和 delete[]

上图中一个Foo占用12个字节

有虚函数多4字节(虚指针)

下图中new Foo[5],理论上应该是60字节,但却是64,

多4字节中存的值是5,表示有5个对象(存的是count),图中construct和destruct箭头表示构造和析构顺序

placement new/delete

Foo* pf = new(300,'c') Foo;

这里总共有3个参数,有一个size_t自动传入

placement delete不会被delete调用,只有当对应new的构造函数出现异常时调用

抛出异常却并没有调用对应的delete重载,为什么呢

侯捷测试老的编译器会调用,但新的不调用 。跟编译器有关。

basic_string 使用placement new(extra) 扩充申请量

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

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

相关文章

赋能 DevOps:平台工程的关键作用

在当今快节奏的数字环境中&#xff0c;DevOps 已成为寻求简化软件开发和交付流程的组织的关键方法。DevOps 的核心在于开发和运营团队之间协作的概念&#xff0c;通过一组旨在自动化和提高软件交付生命周期效率的实践和工具来实现。 DevOps 实践的关键推动因素之一是平台工程。…

市场复盘总结 20240322

仅用于记录当天的市场情况&#xff0c;用于统计交易策略的适用情况&#xff0c;以便程序回测 短线核心&#xff1a;不参与任何级别的调整&#xff0c;采用龙空龙模式 一支股票 10%的时候可以操作&#xff0c; 90%的时间适合空仓等待 二进三&#xff1a; 进级率中 36% 最常用…

使用专属浏览器在国内直连GPT教程

Wildcard官方推特发文说他们最近推出了一款专门为访问OpenAI设计的浏览器。 根据官方消息&#xff0c;这是一款专门为访问OpenAI优选网络设计的浏览器&#xff0c;它通过为用户提供专用的家庭网络出口&#xff0c;确保了快速、稳定的连接。 用这个浏览器的最大好处就是直接用浏…

Linux安装harbor(Docker方式)

Linux安装harbor&#xff08;Docker方式&#xff09; 前置条件&#xff1a;安装docker和docker-compose先下载安装包&#xff1a;https://github.com/goharbor/harbor/releases解压到指定目录 sudo tar -zxf harbor-offline-installer-v2.1.0.tgz -C /opt/安装 cd /opt/harb…

初识STL(标准模板库)

目录 ​编辑 什么是STL STL的版本 STL的六大组件 如何学习STL STL的优势 STL的缺陷 ⭐什么是STL STL(standard template libaray- 标准模板库 ) &#xff1a; 是 C 标准库的重要组成部分 &#xff0c;不仅是一个可复用的组件库&#xff0c;而且 是一个包罗数据结构与算法…

2024年阿里云2核4G服务器优惠价格30元、165元和199元1年

阿里云2核4G服务器租用优惠价格&#xff0c;轻量2核4G服务器165元一年、u1服务器2核4G5M带宽199元一年、云服务器e实例30元3个月&#xff0c;活动链接 aliyunfuwuqi.com/go/aliyun 活动链接如下图&#xff1a; 阿里云2核4G服务器优惠价格 轻量应用服务器2核2G4M带宽、60GB高效…

使用PDFBox调整PDF每页格式

目录 一、内容没有图片 二、内容有图片 maven依赖&#xff0c;这里使用的是pdfbox的2.0.30版本 <dependency><groupId>org.apache.pdfbox</groupId><artifactId>pdfbox</artifactId><version>2.0.30</version></dependency>…

jvm提供的远程调试 简单使用

JVM自带远程调试功能 JVM远程调试&#xff0c;其实是两个虚拟机之间&#xff0c;通过socket通信&#xff0c;达到远程调试的目的&#xff1b; 前提 确保本地和远程的网络是开通的&#xff1b; 本地操作 远程操作 在启动命令参数中 把上面的内容复制进去

基于Java中的SSM框架实现考研指导平台系统项目【项目源码+论文说明】计算机毕业设计

基于Java中的SSM框架实现考研指导平台系统演示 摘要 应对考研的学生&#xff0c;为了更好的使校园考研有一个更好的环境好好的学习&#xff0c;建议一个好的校园网站&#xff0c;是非常有必要的。提供学生的学习提供一个交流的空间。帮助同学们在学习高数、学习设计、学习统计…

图论07-被包围的区域(Java)

7.被包围的区域 题目描述 给你一个 m x n 的矩阵 board &#xff0c;由若干字符 X 和 O &#xff0c;找到所有被 X 围绕的区域&#xff0c;并将这些区域里所有的 O 用 X 填充。 示例 1&#xff1a; 输入&#xff1a;board [["X","X","X",&qu…

css设置div的2个span一个在最左边,一个在最右边

界面&#xff1a; 代码&#xff1a; <html><style>.top span {display: block;position: absolute;margin: 0 20px; /* 添加边距以避免太靠近边缘 */ }.top span:nth-child(1) {left: 5px; /* 调整左侧位置 */ }.top span:nth-child(2) {right: 5px; /* 调整右侧位…

javaweb day21 day22 day23 day24

dql 基本查询 写法 条件查询 写法 聚合函数 写法 分组查询 写法 排序查询 写法 分页查询 写法 案例 写法

量子计算机

近日&#xff0c;在AWS re&#xff1a;Invent全球大会上&#xff0c;亚马逊官宣AWS三箭齐发量子计算组合拳&#xff1a;Braket、AWS量子计算中心和量子解决方案实验室。 随着亚马逊的强势入局&#xff0c;加上此前鼓吹量子霸权的谷歌、起步最早的IBM、暗自发力的微软&#xff…

信号处理--基于通用空间模态(CSP)的脑电通道选择

目录 理论 工具 方法实现 参考文献 理论 通用空间模式&#xff08;CSP&#xff09;是生物医学信号处理领域的一项流行技术&#xff0c;已广泛应用于各种应用&#xff0c;特别是在医疗保健行业。它是一种空间滤波技术&#xff0c;用于从多通道生物医学信号&#xff08;例如脑…

几个常用的控件(2)

目录 一、单选按钮Radiobutton和RadioButtonList 1、Radiobutton控件 &#xff08;1&#xff09;button控制方式 &#xff08;2&#xff09;Radiobutton控制方式 2、RadiobuttonList控件 二、列表框ListBox和下拉列表DropdownList 1、ListBox 2、DropdownList 三、面板…

C语言:数据在内存中的存储

目录 一、 整数在内存中的存储二、 大小端字节序和字节序判断1.什么是大小端2.为什么有大小端3.练习(1)练习1(2)练习2(3)练习3(4)练习4(5)练习5(6)练习6 三、 浮点数在内存中的存储1.练习2.浮点数的存储(1) 浮点数存的过程(2)浮点数取的过程 3.题目解析 一、 整数在内存中的存储…

GB4806.12 竹木材质食品接触餐具厨具检测机构

竹制餐具大多使用竹子作为材质&#xff0c;使用新鲜竹子炮制成型&#xff0c;成型后晒干进行装饰&#xff0c;制作工艺简单快捷&#xff0c;实用性很强&#xff0c;外形美观&#xff0c;实惠好用。很多老一辈人群十分喜欢使用各种竹木制餐具&#xff0c;韧性好&#xff0c;不易…

shell基础编程(一)

引言&#xff1a;之前的初识shell的内容简单的介绍了一下shell&#xff0c;帮助大家认识了一下shell 的组成&#xff0c;这篇文章就具体的讲解shell有关的知识。如果大家有编程基础的话。接下来几篇的文章读起来都会非常容易。没有的话也没有关系&#xff0c;我尽最大的可能讲的…

RabbitMQ是如何保证高可用的?

RabbitMQ可以通过多种方式来实现高可用&#xff0c;以确保在硬件故障或其他不可预测的情况下&#xff0c;消息队列系统仍然能够正常运行。RabbitMQ有三种模式&#xff1a;单机模式、普通集群模式、镜像集群模式。 其中单机模式一般用于demo搭建&#xff0c;不适合在生产环境中…

高项-案例分析练习(范围管理)

案例一 公司在2014年初承接了一个医疗信息系统项目&#xff0c;要求2014年底完成该项目研发任务并进行试运行&#xff0c;2015年负责项目全年的运行维护&#xff0c;运行稳定后甲方验收合格项目才能结束。由于张工具有多年的医疗系统开发管理经验&#xff0c;公司领导任命他为项…