[深度探索C++对象模型](简体版)中的蛇足

深度探索C++对象模型笔记 一、关于对象C 语言是程序性的,语言本身并没有支持数据和函数之间的关联性C++ 中可能采取抽象数据类型,或者是多层次的类结构完成C++ 的封装并没有增加多少成本,每一个成员函数虽然在cla... 阅读详情

 

<深度探索C++对象模型>>(简体版)中的蛇足

(没有此书的人请勿看)

上次见到这本书是一年前(是候先生的繁体版),花了一个星期的时间读完,囫囵吞枣,不求甚解,饶是如此,也解决了我在C++方面的诸多疑惑,这次终于看到了简体版,同样花了一个星期,或许真的是一回生,两回熟吧(也可能是对简体文字的亲切感^_^),思考问题的同时也发现了一些问题,一愚之见,不吐不快。

蛇足之一,P84,

class X {};

class Y : public virtual X {};

class Z : public virtual Z {};

class A : public X, pubic Z {};

书中写到

事实上这个大小受到3个因素的影响,

1)      语言本身所造成的额外负担,。

2)      编译器对于特殊情况所提拱的优化处理。。

3)      Alignment的限制。。

候先生自己添加的示意图如下:

 

当时看这个图真是“百思不得其解”,无论对于Y或Z来说,既然已经从X virtual继承,也就有了的额外的4byte开销,也就是说已经不是一个empty class,那个1 char byte for Y(Z) is empty也就说不通了,而且从lippman的本意来看,

              “2)编译器对于特殊情况所提供的优化处理,virtual base class X的1byte subobject也出现在class Y和Z身上,传统上它被放在derived class的固定(不变动)部分的尾端”,P88中说明,“它把数据直接存放于每一个class object之中,对于继承而来的nonstatic data member(不管是virtual或nonvirtual base class)均是如此”,

因此,我理解的图应该是这样的:

 

也就是说,父类中成员是直接继承到子类中的,只不过对于虚拟继承来说,需要通过一个间接层(表现为某种形式的指针)来存取,这一想法在3.5节(虚拟继承)中再次得到验证,(见P121),书中还提到,empty base class的优化通常把empty base class置于derived class object开头一部分,从而不花费任何额外空间。由此也可以分析出,A的结构如下:(本书中,候先生没有给出这张图)

sizeof(A)为12个byte,在empty base class优化的情况下,为8个Byte。

蛇足之二,P234,

候先生改动了lippman的顺序(指析构时发生的事情),他的根据是“这样才符合ctor的相反顺序”,这也未免太主观了一点,过于咬文嚼字了吧,君不见lippman说“2,dtor的函数本身现在被执行,也就是说vptr会在程序员的码执行之前被重设”,事实上。

struct b {};

struct d1 : virtual public b {};

struct d2 : virtual public b {};

struct d : public d1, d2 {};


Ctor如下: (可参考Vertex3d的ctor)

d()
{
if( __most_derived )
    this->b();

this->d1(false), this->d2(false);

vptr = d::vptr;
// usercode
}

file://编译器扩充dtor如下,按相反顺序。
~d()
{
vptr = d::vptr;    //**//
//user code...

this->~d2(false), this~d1(false);
if( __most_derived )
    this->~b();

}

这不就是lippman的意思吗(见书上从1到5的顺序)?候先生所谓的相反自定义的顺序反而难以理解。

当d被析构的时候,先设vptr = d::vptr,再执行析构函数体,然后依次设d2::vptr, d1::vptr, 最后b::vptr,这些都很容易明白。

而候先生第3点表明“如果object内带一个vptr,则现在被重新设定,指向适当之base class的virtual table”,即认为vptr的设定为跳跃式的,是在~d()中user code 执行完之后(//**//标记的那行不执行),设定vptr 为d2::vptr,然后执行~d2()函数体,最后在~d2()的末尾设定vptr为d1::vptr,再执行~d1(),奇哉!

这可是一个类设定vptr为另一个不相关的类的vptr啊,它们之间可是没有母子关系的噢。个人觉得候先生所制定的顺序过于理论化了,而lippman的方法是从实际出发的。

蛇足之三:P263

class Point

{

public:

       virtual ~Point() {}

};

 

class Point3d : public Point

{

};

 

Point *ptr = new Point3d[10];

for( int ix = 0 ; ix < elem_count ; ++ix )

{

       Point *p = &((Point3d*)ptr)[ix];

       delete p;

}

候先生将之改为:

for( int ix = 0 ; ix < elem_count ; ++ix )

{

       Point3d *p = &((Point3d*)ptr)[ix];

       delete p;

}

这一处很明显,虚拟析构函数用不着指定明显类型,就算指定了类型,都是被resolve成(p->vptr[1])(p),不会带来性能上的改善。

最后指出一点,lippman认为

Point *ptr = new Point3d[10];

delete[] ptr;

“这样做完全不是个好主意(具体解释见P263)”,或许在他那个时候不是吧^_^,但就我在VC6上的测试结果,是完全正确的,所以大家还是可以放心的这样用,(我没有测试其它编译器,有兴趣的可以自己试试)。

佳节之日,仓促成文,恐词不答意,请见谅。
                                                                    19时16分2001/10/1

《深度探索C++对象模型》中文电子版概述 在C++中,我们通过关键字class定义一个类,然后可以创建该类型的实例,也就是对象。例如:public:return 0;在这个例子中,Person类定义了一个成员函数sayHello,然后我们创建了一个Person类型的对象person,并通过它调用sayHello函数。异常安全通常分为三个等级:基本保证、强保证和不抛出保证。基本保证要求在异常发生时,对象处于有效状态但可能与操作前不同。强保证要求如果操作失败,对象应保持操作前的状态不变。 阅读详情

相关推荐

FIFO Generate IP核使用——FIFO写操作详解及Status Flags页配置

本文介绍了FIFO的写操作及Status Flags页的配置信息。

u011565038的博客 2283

《深度探索C++对象模型》..............

《深度探索C++对象模型》… https://dsqiu.iteye.com/blog/1669614 https://blog.youkuaiyun.com/thalo1204/article/details/81571897

nulio_的博客 227

C# 基于NetStandard.Opc.Ua实现高效OPC UA数据订阅与同步读写

本文详细介绍了在C#中利用NetStandard.Opc.Ua库高效实现OPC UA数据订阅与同步读写的方法。通过实战代码演示了如何建立连接、配置订阅管理器、优化监控项分组,并对比了同步与异步读写的适用场景,帮助工业软件开发者构建稳定可靠的数据采集客户端,提升工业物联网应用开发效率。

weixin_29201859的博客 228

深度探索C++对象模型 侯捷

目录 什么是C++对象模型 第一章 关于对象 1.1 C++对象模式 1.2 关键词所带来的差异 1.3 对象的差异 多态 指针的类型 第二章 构造函数语意学 2.1 Default Constructor的构造操作 2.2 拷贝构造器的构造操作 2.3 程序转化语意学 2.4 成员们的初始化队伍 第三章 Data语意学 3.1...

Zy_05_11的博客 3648

VMware Ubuntu虚拟机突然断网?我用5步彻底解决了(附避坑指南)

Ubuntu虚拟机断网问题通常由网络配置冲突和VMware服务未正确绑定导致。本文提供5步解决方案:1)清理Ubuntu重复有线连接;2)重启Windows主机的VMware服务;3)检查VMware虚拟网络配置;4)重新配置Ubuntu网络参数;5)测试网络连通性。关键避坑点包括:避免多连接共存、修改配置后必重启服务、确保虚拟网卡绑定主机。通过"网卡状态→IP/路由→网关→服务"的排查思路,可快速解决虚拟机网络故障。文末附有详细的故障症状对照表,便于快速定位问题。

m0_58530495的博客 626

Python3.8下MvCameraControl.dll加载失败?3种方法彻底解决FileNotFoundError

本文针对Python3.8及以上版本在Windows平台调用MvCameraControl.dll时出现的FileNotFoundError问题,深入剖析了其根源在于Python 3.8引入的DLL加载安全机制变更。文章提供了三种核心解决方案:显式指定DLL完整路径、使用os.add_dll_directory()添加可信目录,以及利用ctypes的winmode参数进行精细控制,并给出了工程化封装建议,帮助开发者彻底解决此兼容性问题。

weixin_29093017的博客 191

[读书笔记] - 《深度探索C++对象模型》第5章 构造、解构、拷贝语意学

1.纯虚函数 纯虚函数可以被定义和调用,不过它只能被静态地调用,不能经由虚拟机制调用。 // 定义pure virtual function inline void Abstract_base::interface() const { } inline void Concrete_derived::interface() const { // ok: 静态调用 Abstract_base::interface(); } 要不要定义纯虚函数,全由class设计者决定。但是pure

浮生的博客 360

Appsflyer Web2App实战指南:OneLink与Web SDK深度对比

本文深入对比了Appsflyer实现Web2App的两大核心工具:OneLink智能链接与Web SDK。OneLink提供开箱即用的智能跳转,部署快捷,适合快速推广;Web SDK则支持高度自定义的用户行为追踪,适合深度分析与精细化运营。文章提供了详细的配置指南、场景化选型建议及实战避坑技巧,帮助营销与开发团队根据自身需求选择最佳方案,有效提升从网页到应用的转化率与归因精度。

weixin_29213655的博客 458

C++对象构造与析构全流程

对象构造流程 1. 首先,如果有virtual base class constructors,虚基类的构造函数必须被调用,从左往右,从深往浅: -&gt;如果有virtual base class constructor位于成员初值列,有任何显示指定的参数都应该传递过去;若没有位于初值列,而virtual base class含有一个默认构造函数,也应该调用。 -&gt;class中的...

Innocent_code的专栏 812

Win10安全模式下修改C盘权限的完整指南(附解决开始菜单失灵方案)

本文提供了一份在Win10安全模式下修复因C盘权限误改导致开始菜单失灵的完整指南。文章深入剖析了权限体系,特别是TrustedInstaller角色的重要性,并详细讲解了通过安全模式进入系统、使用ICACLS命令或图形界面精准重置C盘关键目录权限的步骤,最终恢复系统核心功能。

weixin_29250403的博客 234

1、符号回归:原理、应用与实践

本文全面介绍了符号回归(Symbolic Regression)的原理、发展历程、核心算法及其在科学与工程领域的广泛应用。文章从基本概念出发,详细阐述了基于遗传编程的符号回归机制,并探讨了其在游艇水动力学、化学过程、锂离子电池、生物医学等多个领域的实际应用。同时,博文还涵盖了高级技术如知识集成、系数优化、预测区间计算及微分方程发现等内容,对比了开源与商业软件工具,并展望了未来发展趋势,旨在为研究人员和从业者提供一本实用的符号回归指南。

ipfs8storage的博客 248

《深度探索C++对象模型》读书笔记第五章:构造析构拷贝语意学

《深度探索C++对象模型》读书笔记第五章:构造析构拷贝语意学 对于abstract base class(抽象基类),class中的data member应该被初始化,并且只在constructor中或者在其他member functions中指定初值。 纯虚函数的存在 纯虚函数,虚函数在声明后加上 = 0,纯虚函数的意义在于只定义一个可继承的接口,并没有实现(虚函数意义在于定义一个可继...

yhcuac 1027

STM32CubeIDE开发环境搭建与GPIO控制实战

嵌入式开发中,MCU开发环境构建是软硬件协同的起点,其核心在于工具链选型、外设抽象层级与调试可靠性。HAL库作为ST官方标准硬件抽象层,通过统一接口屏蔽芯片差异,显著提升工程可移植性;而STM32CubeIDE则以图形化配置+自动生成代码的方式,实现‘配置即代码’的确定性开发范式。该组合在教学验证、原型迭代和中小规模量产中具备高性价比技术价值,广泛应用于智能传感、工业HMI及IoT终端等场景。本文聚焦STM32CubeIDE 1.15.0环境部署、MyST账户与固件包管理、ST-LINK驱动校验,以及基于H

weixin_33531560的博客 80

<<深度探索C++对象模型>>(简体版)中的蛇足 (转)

<>(简体版)中的蛇足 (转)[@more@] 对象模型>>(简体版)中的蛇足 (没有此书的人请勿看) 上次见到这本书是一年前(是候先生的繁体版),花了一个星期的时间读完,囫囵吞枣,不求甚解,饶是...

csd3176的博客 101

NTscan扫描工具

ntscan是一个扫描器,可以扫描没有密码和弱密码的共享,先到配置文件中填写猜测的用户名和密码,扫描过程中右侧出现的是扫描日志。

VC中sqlite的使用

在VC中对sqlite的使用,实现数据库大批数据的快速插入,读取数据库中的数据在ListCtrl中显示

学习《深入理解C++对象模型》小结

周天阳的记事本http://hi.baidu.com/zhoutianyang/blog/item/9c1e4b16fda8334b21a4e915.html Chapter 2 构造函数语义学习小结1、 C++编译器何时会为C++中的类生成缺省的构造函数(Default constructor)?如果程序员没有定义构造函数,编译器会在下面四种情况为类生成缺省的构造函数:?      

wangjun_1218的专栏 2898

Probability and Statistics - 4th edition

Probability and Statistics - 4th edition

深度探索C++对象模型之美

从概念来上来讲,每一个没有定义构造函数的类都会由编译器来合成一个默认构造函数,以使得可以定义一个该类的对象,但是默认构造函数是否真的会被合成,将视是否有需要而定。C++ standard 将合成的默认构造函数分为 trivial(不重要) 和 notrivial(重要) 两种,前文所述的四种情况对应于notrivial默认构造函数,其它情况都属于trivial。对于一个trivial默认构造函数,编译器的态度是,既然它全无用处,干脆就不合成它。

谢谢大家的关注 3494

LinePhone3.2.7(android端最新版本) sip客户端

SIP客户端For android:LinePhone3.2.7(最新版本),官网地址:http://www.linphone.org/

深度探索C++对象模型

深度探索C++对象模型参考链接:第1章 关于对象C++的额外成本三种对象模型简单对象模型表格驱动对象模型C++对象模型class和struct关键字的差异三种编程典范一个类的对象的内存大小一些结论[^3] 参考链接: 深度探索C++对象模型 笔记汇总 第1章 关于对象 C++的额外成本 C++较之C的最大区别,无疑在于面向对象。类相较于C的struct不仅只包含了数据,同时还包括了对于数...

zzxiaozhao的博客 3752

《深度探索C++对象模型》阅读笔记(完整版)

《深度探索C++对象模型》完整阅读笔记

2401_82413779的博客 1903

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

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

DWATER 6126

深度探索C++对象模型:解锁编程的底层奥秘

深度探索C++对象模型:解锁编程的底层奥秘 【下载地址】深度探索C对象模型资源下载 深度探索C++对象模型资源下载 项目地址: https://gitcode.com/Open-source-documentation-tutor...

gitblog_06650的博客 1073

【亲测免费】 深度挖掘C++奥秘:《深度探索C++对象模型(清晰版)》—— 开启你的专家之路

深度挖掘C++奥秘:《深度探索C++对象模型(清晰版)》—— 开启你的专家之路 【下载地址】深度探索C对象模型清晰版资源下载分享 深度探索C++对象模型(清晰版)资源下载 项目地址: https://gitcode.com/Ope...

gitblog_06646的博客 752

【免费下载】 深度探索C++对象模型 超高清PDF资源下载

深度探索C++对象模型 超高清PDF资源下载 【下载地址】深度探索C对象模型超高清PDF资源下载 - **文件名**: 深度探索C++对象模型 超高清pdf- **文件格式**: PDF- **文件大小**: [文件大小]- **分辨率**: 超高清 ...

gitblog_06684的博客 1955

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

文章目录前言第一章 关于对象第二章 构造函数语意学构造函数拷贝构造函数初始化列表第三章 Data 语意学第四章 Function 语意学非静态成员函数静态成员函数虚成员函数第五章 构造、析构、拷贝语意学RTTI模板函数的实现逻辑 前言 俗话说得好,好记性不如烂笔头,本文主要是重温了一下经典书籍《深度探索C++对象模型》,然后一些内容摘录,主要记录的是我自己的精简版,建议读者有相关的知识需要还是慢慢去啃一下原书比较好。 第一章 关于对象 首先介绍了 C++ 类的情况, C++类的内存存储方式是:只包含非静态成

Chris_zhangrx的博客 1482

【免费下载】 深度探索C++对象模型 PDF

深度探索C++对象模型 PDF 【下载地址】深度探索C对象模型PDF 深度探索C++对象模型 PDF欢迎来到《深度探索C++对象模型》PDF资源页面 项目地址: https://gitcode.com/open-source-to...

gitblog_09794的博客 784
上一篇: 静态初始化--我的理解
下一篇: 令人困惑的return by value
招RD和QA
博客等级 码龄26年 40粉丝 34原创
评论 1
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

个

红包个数最小为10个

元

红包金额最低5元

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

抵扣说明:

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

余额充值