深入探索C++对象模型 之 执行期语意学

线性代数知识点整理 线性代数基础知识点摘要整理 阅读详情

在C++ 中的一件很困难的事,就是不太容易从程序代码看出表达式的复杂度。

如下面语句:if ( yy.operator = = ( xx.getValue () ) ) )将被扩展为下面这样的C++伪码:

{

  X temp1 = xx.getValue ();

  Y temp2 = temp1.operator Y();

  Int temp3 = yy.operator = = ( temp2 );

  If ( temp3 ) …

  Temp2.Y::~Y ();

  Temp1.X::~X();

}

 

对象的构造和解构

构造函数一般在对象被构造后调用,而解构函数必须被放在每一个离开点(当时object还存活)只前调用。一般而言我们会把object 尽可能放置在使用它的那个程序区段附近,这样做可以节省不必要的对象产生操作和摧毁操作。

 

全局对象

C++ 保证,一定会在main() 函数中第一次用到global 变量之前,把global 变量构造出来,而在main() 函数结束之前把global 变量摧毁掉。一个global object 如果有 constructor 和destructor 的话,我们说它需要静态的初始化操作和内存释放操作。

被静态初始化的object 有一些缺点:

1.       如果exception handling 被支持,那些objects 将不能够被放置于try 区段之内。

2.       为了控制“需要跨越模块做静态初始化”objects 的相依顺序而扯出来的复杂度。

所以建议不要用那些需要静态初始化的global objects。

 

局部静态对象

它的constructor 和 destructor 必须只能施行一次,虽然上述函数可能会被调用多次。

只有当含有local static objects 的函数被调用时才会把local static objects 构造出来。

它们的destructors 顺序也和constructors 的调用顺序相反。

 

对象数组

vec_new() 和vec_delete() 函数将被调用来逐一调用数组里每个对象的constructor 和 destructor。

如:Point knots [ 10 ];

会调用:

vec_new ( &knots, sizeof ( Point ), 10, &Point::Point, 0 );

 

New 和 delete 运算符

如:Int *pi = new int ( 5 );

实际上是分两步执行:

Int *pi;

If ( pi = _new ( sizeof ( int ) ) )

*pi = 5;

以 constructor来配置一个class object,情况类似:

Point3d *origin = new Poit3d;

变成:

Point3d *origin;

If ( origin = _new ( sizeof ( Point3d ) ) )

  Origin = Point3d::Point3d ( origin );

如果实现出 exception handling,那么转换结果可能会更复杂些:

if ( origin = _new ( sizeof ( Point3d ) ) ){

  try{

    origin – Point3d::Point3d ( origin );

}

  catch(…){

      _delete ( origin );

throw;

}

  }

}

destructor 的应用极为类似:

delete origin;

会变成:

if ( origin != 0 ){

  Point3d::~Point3d ( origin );

  _delete ( origin );

}

一般的library 对于 new 运算符的实现操作有两个精巧之处:

extern void* operator new ( size_t size )

{

if ( size = = 0 )

  size = 1;//为了每次传回一个独一无二的指针。

void *last_alloc;

while ( !( last_alloc = malloc ( size ) ) )

{

if ( _new_handler )//允许使用者提供一个属于自己的_new_handler() 函数。

( *_new_handler ) ();

else

       return 0;

}

return last_alloc;

}

 

针对数组的new 语意

如:int *p_array = new int [ 5 ];

变成:

int *p_array = ( int* ) _new ( 5 * sizeof ( int ) );

再如有constructor 函数的对象数组的new 语意:

Point3d *p_array = new Point3d [10 ];

变成:

Point3d *p_array;

P_array = vec_new ( 0, sizeof ( Point3d ), 10, &Point3d::Point3d, &Point3d::~Point3d );

最好避免以一个base class 指针指向一个derived class objects 所组成的数组——如果derived class object 比其base 大的话。因为在delete 的时候不会调用derived class 的destructor 函数。如过非得那样写,就把base class 指针强制转换成derived class 指针在 delete。

 

Placement Operator new 的语意

Point2w *ptw = new ( arena ) Point2w;

实际代码是:

Point2w *ptw = ( Point2w* ) arena;

If ( ptw != 0 )

  Ptw->Point2w::Point2w ();

当你想用placement operator 在原已存在的一个object 上构造新的object,而该现有的 object 有一destructor,那么应该用 placement operator delete 来调用它的destructor。

C++说arena 必须指向相同类型的class,要不就是一快“新鲜”内存,足够容纳该类型的object。但是,derived class 很明显不在被支持之列。对于一个derived class,或是其他没有关联的类型,其行为虽然并非不合法,却也未经定义。

“新鲜”的储存空间可以这样配置而来:

char *arena = new char [ sizeof ( Point2w ) ];

相同类型的object 则可以这样获得;

Point2w *arena = new Point2w;

Placement new operator 并不支持多态。被交给new 的指针,应该适当地指向一快预先配置好的内存。

 

临时性对象

在某些环境下,由processor 产生临时性对象是有必要的,亦或是比较方便的。这样的临时性对象由编译器来定义。

初始化操作:

T c = a + b;//将不产生临时对象

总比下面的操作更有效率地被编译器转换:

c = a + b;//会产生临时对象

a + b;//也会产生临时对象

临时性对象的被摧毁,应该是对完整表达式求值过程中的最后一个步骤。该完整表达式造成临时对象的产生。

。。。。。。凡含有表达式执行结果的临时性对象,应该存留到object 的初始化操作完成为止。

如果一个临时性对象被绑定于一个reference,对象将残留,直到被初始化之reference 的生命结束,或直到临时对象的生命范畴结束——视哪一种情况先到达而定。

资源分享·病毒样本下载资源分享 一、微步云沙箱 微步在线云沙箱https://s.threatbook.cn/ 使用病毒sha256即可寻找病毒样本;该站点也可上传可疑文件/可疑URL地址到沙箱中,进行分析 。 以永恒之蓝为例,样本sha256是:ed01ebfbc9eb5bbea545af4d01bf5f1071661840480439c6e5babe8e080e41aa 下载样本或流量监控,需要消耗积分: 二、AnyRun Interactive Online Malware Analysis Sandbox. 阅读详情

相关推荐

FID指标实战:如何用Python快速计算生成图像的质量分数(附完整代码)

本文详细介绍了如何使用Python计算Fréchet Inception Distance(FID)指标,以评估生成图像的质量。通过完整的代码示例和优化技巧,帮助开发者快速实现FID计算,并解读分数背后的实际意义,适用于GAN和扩散模型的性能评估。

weixin_28718487的博客 377

深入探索C++对象模型(十一)执行期语义学(临时对象)

关于临时对象的几条准则。1. 在某些情况下,编译器可以产生必要的,或者可以带来方便的临时对象,具体行为由编译器来定义。例如,对于如下操作:[cpp] view plain copyT a, b;  T c = a + b;//T operator+ (const T&, const T&)  a. 编译器会产生一个临时对象,放置a+b的结果,然后使用T的拷贝构造函数,把临时对象当作...

coolwriter的博客 375

基于STM32的家用新风系统智能控制器 | 保姆式教程 开源可复刻

本项目基于STM32F103C8T6核心控制器,完整实现了家用新风系统智能控制器的全功能开发,覆盖多传感器数据采集、双模式控制、PID调速、异常报警、掉电记忆等核心功能,全程采用保姆式无跳步教学,从硬件选型、接线、CubeMX配置、代码开发、调试排坑全流程拆解,跟着步骤一步步操作,就能顺利完成项目复刻

ZhongWeiXiang9的博客 468

深度探索C++对象模型:6.执行期语意学

第6章:执行期语意学 想象一下我们有下面这个简单的式子: if(yy ==xx.getValue())... 其中xx和yy定义为: Xxx; Yyy; ClassY定义为: ClassY{ Public: Y(); ~Y(); Booloperator==(constY&)const; //... }; ClassX定义为: ClassX{ Public:...

系统 运维 287

维护测试监控LLM应用

LangFuse: 开源 + SaaS(免费/付费),LangSmith 平替,可集成 LangChain 也可直接对接 OpenAI API;LangSmith: LangChain 的官方平台,SaaS 服务(免费/付费),非开源,企业版支持私有部署;调试 Prompt 的 Playground测试/验证系统的相关指标数据集管理各种指标监控与统计:访问量、响应时长、Token 费等等。

SunnyRivers 1783

C++常见面试题总结

C++常见面试题总结

xu_fu_yong的专栏 8万+

C++不允许在函数的try中使用static局部变量的原因

在《INSIDE C++ MODEL》书中247页提到了如下一段话: “shiyon给被静态初始化的objects,有一些缺点。例如,如果exceptiony handling被支持,那些objects将不能够被放置于Atry区段之内...." 想了一段时间才想明白这个问题,下面用一段代码来说明一下: A.cpp class A { } int main() {

CHALLENG_EVERYTHING的专栏 812

展会客流统计的客流统计系统,WiFi客流每时每客

一般展会的举行时间都在3-7天之间,展会作为市场部门一项重要工作,一直以来没有一项有效的工具能够提供数据支持。 展会最重要的是通过活动和产品来吸引参展者的参观,如何统计展会期间的客流量呢?如何通过将数据转化成为活动数据的支撑呢? 目前成熟的解决方案有,视频客流统计、WiFi客流统计、红外线客流统计等方式。由于展会通常的时间都比较短,视频、红外线客流统计采购及安装价格都比较高,需

isentech的博客 3996

深入探索C++对象模型(十)执行期语义学(new和delete)

关于new和delete运算符。a. 使用new运算符构造对象时, 例如:[cpp] view plain copyPoint3d* origin = new Point3d;  会被转化为两个操作:分配空间和调用类的构造函数:[cpp] view plain copyPoint3d* origin;  if(origin = __new(sizeof(Point3d)))  {      ori...

coolwriter的博客 334

openEuler 欧拉 安装Oracle19c数据库RPM包安装

欧拉系统安装部署oracle 19c rpm方式

陈苏漾的IT生涯 6894

波浪补偿控制(AHC)之波浪发生器(CODESYS完整源代码)

波浪发生器平台详细算法和结构介绍请参看下面博客文章:CODESYS平台如何建立FC和FB,请参看下面博客文章:

RXXW_Dor的博客 402

C++对象模型——异常处理 (Exception Handling)(第七章)

7.2    异常处理 (Exception Handling)     欲支持exception handling,编译器的主要工作就是找出 catch 子句,以预处理被丢出来的exception.这多少需要追踪程序堆栈中每一个函数的当前作用区域.同时,编译器必须提供某种查询exception objects的方法,以知道其实际类型(这直接导致某种形式的执行期类型识别,也就是RTTI).最后,

yiranant的专栏 1586

Vue3 - 详细实现调用浏览器摄像头拍照并生成图片预览,支持将抓拍的图像保存到用户本地或上传到服务器、调取前置摄像头和后置摄像头,开启摄像头并进行拍照,vue实现调用摄像头,电脑或手机调用摄像头拍照

vue3,nuxt3,摄像头,vue3网站打开摄像头拍照,vue3项目调用摄像头实现拍照功能,拍照后怎么保存,照相后上传到后端服务器,开启摄像头黑屏,如何默认后置摄像头,网页开启电脑摄像头并照相,前置拍照,vue3如何调用手机摄像头进行拍摄,拒绝权限后不再弹出了,微信公众号网页,摄像头报错,拍照左右镜像反了,浏览器不兼容怎么办,vue3调用电脑端摄像头实时拍照,解决调用摄像头权限无法弹出,打不开摄像头,Vue3如何调用手机的摄像头,调用本地摄像头实现拍照,浏览器不弹摄像头权限了,如何不使用https运行测试

🏆 前端领域优质创作者 8654

【C++】深度探索C++对象模型之执行期语意学

执行期语意学,即在程序执行时,编译器产生而外的指令调用,确保对象的构造,内存的释放,以及类型转换与临时对象的生成的安全进行。 一、对象的构造和析构 对于类对象的构造,我们应该尽量在需要使用时才进行定义,一般在定义之后则开始内部的构造过程。 而对于已构造的对象,其析构函数必须放在每一个离开点(当object还存在)之前。 二、全局对象 对于全局变量,C++会保证在调用全局变

小do在努力 1122

大中型超市收银系统(可直接运行)

光步前台收银系统系统功能:商品销售、商品退货、挂单、收银员权限、会员销售、单品取消、整单取消、商品查询、脱机销售、脱机数据上传,基本资料下载,开钱箱、小票打印、收款结算,支持多币种付款方式(现金、储值卡、礼券、微信等),支持多种促销。运行环境:.net 4.0登陆信息用户名:1001 密码:123456内置商品信息,商品编码可输入00001000 - 00010000,测试效果相关功能键F5 结算 F9挂单 F11商品查询 F8退货 Insert单品取消 Del整单取消 F12开钱箱F2 会员 Ctrl+Z退出系统 Home 锁屏 相关源码待公开

蓝牙模块HM-10手册

蓝牙模块HM-10手册,该手册对蓝牙模块HM-10进行了详细的介绍和使用方法以及一些AT指令。

深入探索C++对象模型之六 --- 执行期语意学

深入探索C++对象模型之六 — 执行期语意学

Aaron的专栏 592

Probability and Statistics - 4th edition

Probability and Statistics - 4th edition

《深度探索C++对象模型》笔记目录

读书笔记,特此记录。 😇😇😇 《深度探索C++对象模型》阅读笔记 第一章 关于对象 《深度探索C++对象模型》阅读笔记 第二章 构造函数语意学 《深度探索C++对象模型》阅读笔记 第三章 Data语意学 《深度探索C++对象模型》阅读笔记 第四章 Function语意学 《深度探索C++对象模型》阅读笔记 第五章 构造、解构、拷贝语意学 《深度探索C++对象模型》阅读笔记 第六章 执行期语意学 《深度探索C++对象模型》阅读笔记 第七章 站在对象模型的尖端...

哇咔咔的博客 364

android 蓝牙通讯demo

android 下蓝牙通讯demo,实现了发现蓝牙,使能蓝牙,通过蓝牙发送消息。

《深度探索C++对象模型》读书笔记之执行期语意学

1、  如何查看objectfiles中定义的函数和全局变量? 好吧,其实这个问题确实与执行期语意学有关。因为编译器需要收集每个全局变量的构造和析构函数,而其实现方式也是使用nm命令打印object file的符号表找出特定开头的名称。所以咯,答案是nm命令。(腾讯面试中,我曾遇到这个,当时没答出来T_T)   2、  operator new()、placement new()与new关键

Al_xin的专栏 922

《深度探索C++对象模型》阅读笔记 第六章 执行期语意学

如果一个区段(译注:以 { } 括起来的区域)或函数中有一个以上的离开点,情况会稍微混乱一些。Destructor必须被放在每一个离开点(当时object还存活) 一般而言我们会把object尽可能放置在使用它的那个程序区段附近,这样做可以节省不必要的对象产生操作和摧毁操作,由于这样的限制,下面这些munch策略就浮现出来了: 因为静态语意保证了 mat_identity 在整个程序周期都存在,而不会在函数 identity()退出时被析构,所以:以下就是书中作者在cfront之中的做法。首先,我导人一个临

哇咔咔的博客 381

问答学习《深度探索C++对象模型》系列

经过数次翻看《深度探索C++对象模型》和翻看别人的笔记,还是决定自己动手写一下该本书的笔记。笔记采用问答的方式是因为在UC实习时我的指导老师的影响:你不要为了看书而看书,你要从中学到东西就要带着疑问去学习。于是有了这一系列的笔记,感谢我的指导老师让我明白:生命不息,学习不止。 第一章:《深度探索C++对象模型》读书笔记之关于对象 第二章:《深度探索C++对象模型》读书笔记之构造函数语意学 第

冰枫的随笔 1336

深度探索C++对象模型——6_执行期语意学

深度探索C++对象模型

wogan101的博客 248

《深度探索C++对象模型》第六章 执行期语意学

new运算符和delete运算符 运算符new看似是一个简单的运算,比如:int *pi=new int(5);但是它实际由两个步骤完成: 1.通过适当的new运算符函数实体,配置所需的内存://调用函数库中的new运算符 int *pi=__new(sizeof(int));2.给配置得到的对象分配初值:*pi=5;(注意,上面的代码中并不包括 exception handling,是

李正浩的博客 514

【深度探索C++对象模型】第六章 执行期语意学

对象的构造和析构如果一个区段或函数中有一个以上的离开点,destructor必须被放在每一个离开点之前。一般而言object应尽可能放在使用它的那个程序区附近,这样做可以节省不必要的对象产生和销毁操作。C++程序中所有的global objects都被放置在程序的data segment中。如果global object有constructor和destructor的话,它需要静态的初始化和内存释...

stt2019 235

《深度探索C++对象模型》读书笔记

 Inside The C++ Object ModelStanley B. Lippman 屋檐下的水滴--读书笔记系列http://blog.youkuaiyun.com/dwater 《深度探索C++对象模型》读书笔记                                                                          

DWATER 6126

《深度探索C++对象模型》学习笔记

《深度探索C++对象模型》学习笔记 最近学习了c++对象模型,做下笔记,方便日后查阅 第一章:关于对象 c++对象模型 在此模型中,成员变量被配置在每一个对象中,静态成员变量、成员函数和静态成员函数放置在对象之外,虚函数则以下两个步骤支持: 每个类产生一堆指向虚函数的指针放在表格之中,这个表格叫做虚函数表(vtal) 每个对象中被添加一个指针(vptr),指向相关的虚函数表,vptr的赋值和重置由每个类的构造函数、析构函数和拷贝赋值运算符自动完成。每个类所关联的type_info放在虚函数表的表头

QT练手小程序 466

《深度探索C++对象模型》读书笔记第六章:执行期语意学

《深度探索C++对象模型》读书笔记第六章:执行期语意学 C++在执行期的一些变化,例如临时对象的产生,临时对象的构造和析构成本是我们需要考虑的,我们将在第三节具体讲解。 一.对象的构造和析构 一般而言,我们将object尽可能放置在使用它的那个程序区段附近,这样可以节省非必要的对象的构造和析构成本。 全局对象 已经初始化全局对象均存储在data segment(数据段),未初始化...

yhcuac 564

《深度探索C++对象模型》--5 构造析构拷贝 && 6 执行期语意学

《深度探索C++对象模型》--5 构造、析构、拷贝语意学 1、纯虚函数: (1)C++可以定义和调用一个纯虚函数,不过只可以静态调用,不可以由虚拟机制调用。 注意:pure virtual destructor一定得定义,因为每一个derivedclass destructor会被编译器加以扩张,以静态方式调用其每一个virtual base class及上一个ba

KUAILE123的专栏 1171
上一篇: 深入探索C++对象模型 之 构造,解构,拷贝语意学
下一篇: 深入探讨C++对象模型 之 站在对象模型的尖端
C_plus_learner
博客等级 码龄22年 0粉丝 9原创
评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

个

红包个数最小为10个

元

红包金额最低5元

当前余额3.43元 前往充值 >
需支付:10.00元
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付元
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值