深度搜索C++对象模型 - 数据语义学

把开源 Skills 集成到 LangGraph 项目 1. 定义智能体状态(必须包含 messages,其他字段按需扩展)messages: List[HumanMessage | AIMessage | ToolMessage] # 消息流(核心)skill_output: Optional[str] # 存储 Skill 执行结果next_node: str # 控制流程跳转# 2. 定义智能体决策节点(决定是否调用 Skill)"""智能体决策逻辑:根据用户输入判断是否调用开源 Skill"""# 获取最后一条用户消息。 阅读详情


深度搜索C++对象模型: Data Semantics

//*********************************************************************************************//

---> "虚拟继承的 sizeof 问题":
class X { };
class A : virtual public X { };
class B : virtual public X { };
class Y : public A, public B { };

对他们分别取sizeof 输出的结果为 : 1 4 4 8;
对于class X来说, 他里面没有任何东西 但是编译器会安插进去一个char, 使得class X的两个object得以在内存中配置独一无二的地址
对于class A和class B来说, 他们内部是虚拟继承的 所以编译器会安插一根虚拟继承指针, 这根指针为4字节, 这根指针指向了virtual base class;
对于class Y来说, 他继承了A和B的两根虚拟继承指针 所以大小为8;

对于类的大小 有三个影响因素:
--> 语言本身造成的额外负担: 语言本身支持了 virtual base class, 就会造成一些负担( 一根虚拟继承指针 );
--> 编译器对于特殊情况提供的优化处理: 照理说class A和class B也该继承class X的一字节char, 但是已经没有必要了 所以编译器优化掉了;
--> 对齐限制: 内存需要对齐, 内存大小必须为最大存储长度的整数倍;


class X { int m_num; };
class A : virtual public X { };
class B : virtual public X { };
class Y : public A, public B { };

对他们分别取sizeof 输出的结果为 : 4 8 8 12;
对于class X来说, 他里面有一个int类型数据 大小自然为4字节;
对于class A和class B来说 他是虚拟继承 所以编译器安插了一根虚拟继承指针( 4字节 ), 而他又继承了class X的一个int数据( 4字节 ), 所以一共8字节;
对于class Y来说, 如果"抛开虚拟继承" 那么他的大小应该是"父类大小和 8 + 8 = 16"; 但是Y的一个实体里面包含了两份X的拷贝;
所以提出了虚拟继承,虚拟继承之后Y的实体里只包含一份X的拷贝 所以是 4 + 4 + 4 = 12;

//-----------------------------------------------------------------------------------------------------------------------//

---> "Data Member 的布局":
class A
{
 int a;
 bool b;
 bool c;
};

class X
{
 int a;
};

class Y : public X
{
 bool b;
};

class Z : public Y
{
 bool c;
};

对他A和Z分别取sizeof 输出的结果为 : 8 12;
先分析class A, class A中的三个变量 必须符合"较晚出现的必须有较高的地址" 通俗点就说 顺序存储. 又由于内存对其 所以 4 + 1 + 1 + 2 = 8;
而对于class Z, 他继承了2个变量a b,和一个自己的变量c, 但是他的存储方式为 先构造X 在构造Y 在最后构造Z 结果为 4 + 1 + 3 + 1 + 3 = 12; ( 后文分析 )

对于非静态成员变量 他直接被放到了 class object 中,  除非经过显示或者隐式的 class object 否则无法存取, 事实上就是( this );

//-----------------------------------------------------------------------------------------------------------------------//

---> "继承与 Data Member":
在C++继承模型中, 一个派生类所表现出来的东西, 是其自己的成员加上他基类成员的综合, 至于他们的排列顺序 并无规定
( VS2012 基类在上头, 但是属于 virtual base class 除外, 因为任何一个规则碰上他 都完蛋 );

--> "只要继承不要多态":
对于只继承来说 单纯只是把基类成员放在上头, 派生类成员放在下头就结束了,
回头看上面的问题 为什么是 8 12 ? 为什么编译器不把 bool c 填充到前面空下的3字节空间里 ?

X px_1, px_2;
Y py_1;

其中px_1, px_2 都可以指向X Y Z三种class object;

*px_2 = *px_1;
此时 发生的是一个默认的"位逐次拷贝"复制操作,  "复制对象 object 的 X 那部分";
( 如果 px_1 指向Y或Z的class object, 则上述操作应该将复制内容指定给其X的子对象 )

然而 如果如果C++把 bool c 填充到前面的3字节空间里:
px_1 = py_1;
*px_2 = *px_1;

让px_1指向了py_1之后, 如果发生了 某个 object 的 X subobject 的复制操作的时候, 就会使得结果有一个出乎意料的结果. 多出来了 Y subobject 的内容;

--> "加上多态":
class A
{
 public:
 int m_num1;
 virtual void Func1() { };
};

class B : public A
{
 public:
 int m_num2;
 virtual void Func1() { };
 virtual void Func2() { };
};

对于类A, 他内含有一个虚函数 而继承了他的类B 也自然包含了继承而来的虚函数, 而且类B还有了一个自己的虚函数,
那么类A和类B在编译时就会自动产生一个 virtual table, 然后在 class object 中内插一根 vptr;
( 对于class A, 这个virtual table中只有func1(), 对于class B, 这个virtual table有func1() 和 func2();
那么class A的vptr指向只有func1()的vtbl,  class B的vptr指向有func1()和func2()的vtbl );

对于C++来说 这根class object内的vptr放在那 ? 结论是可以是任何地方 并没有规定 但是一般放在头尾
( 经过测试 VS2013 把 vptr 放在了起始 )

对于上述类B的内存分布:
vptr -> m_num1 -> m_num2
如果上述类A和类B中没有Func1(); 即基类无虚函数,而派生类有虚函数
m_num1 -> vptr -> m_num2

--> "多重继承":
单一继承提供了一种"自然多态"形式, 主要说的是 base type 和 derived type 之间的转换:
A *a;
B *b = new B;
a = b;
这个转换是很自然的 因为 base type 和 derived type 是从同一地址开始的, 唯一的差异是 derived type 比较大;
此时把 derived class object 指定给 base class 的指针 是很自然的 不违反 base class 的解释规则 所以是"自然多态";

但是当派生类型为多重继承或者虚拟继承时 , "自然多态就会被打破":
class A { };
class B : public A { };
class C { };
class Z : public B, public C { };
( 注:所有类都有virtual接口 )
例如 将一个 Z class object 转换为 C class object 为"不自然的"

对一个多重派生对象, 其地址指定为"最左端" base class 的指针 ( class Z 的地址为 class B 的地址 )
第二个或后继的 base class 的地址指定操作, 则需要将地址修改 加上介于中间的 base class subobject大小
例如:
Z z;
A *a = &z;  // 0x00000000
B *b = &z;  // 0x00000000
C *c = &z;  // 0x00000004  ( 因为介于之间的 base class 为 class B, 而sizeof( B ) = 4 )

在来说一下: " &z == c; "
结论是 为真, 为什么为真?
首先我们先判断一下上面发生了什么; 当我们进行 C *c = &z; 的时候 编译器会进行一次强制类型转换
然后编译器发现是多重继承 则按照我们所说的 "地址修改规则" 修改过地址之后 赋值给c 结果c的地址和z的地址不一样了;
那么" &z == c; " 发生了什么? 当我们对 &z 和 c 进行 == 判断的时候; 编译器会对其进行一个 "类型转换",
他会"把 ( Z * ) 的指针 强制转换为 ( C * ) 类型的指针", 说简单点就是 &z 被强转成了 C * 类型
那么由于 == 所带来的副作用 两个不同类型的数比较 会转换为两个类型中较大的类型
那么 " &z == c; " 操作最后实际上还是会把 &z 经过 上面多重继承的 "地址修改规则" 最后 &z == 0x00000004; 而 c == 0x00000004; 所以equl

最后 以上多重继承的内存结构如下: ( 基于VS2013 ) sizeof( Z ) == 8;
vptr_A -> vptr_C

//-----------------------------------------------------------------------------------------------------------------------//

---> "虚拟继承":
class A { };
class X : virtual public A { };
class Y : virtual public A { } ;
class Z : public X, public Y { };
( 所有类都有virtual接口 )
对于方式的原版 无虚拟继承时, Z中会维护两份A的拷贝,
实现虚拟继承, 我们需要找到一个足够有效的办法, 将X和Y格子维护的一个A object 折叠成为一个由Z维护的单一的A object;
而且还需要保存base class 和 derived class的指针以维持多态操作;
一般的实现方法为: 如果一个 class 内含一个或多个 virtual base class subobject( 类似Z ), 那么他将会被分为两部分,
一个不变区和一个共享区:
不变区不管类如何继承, 他都有固定的offset, 可以直接寻址,
而共享区的数据( 其实就是 virtual base class 部分的数据 ), 他们只能被间接寻址,

具体来说( 基于VS2013 )
每一个 class object 如果有一个或多个 virtual base class, 那么编译器会生成一个 virtual base class table, 里面放这 virtual base class 的指针;
然后在 class object 内安插一根指向 virtual base class table 的指针 ( 这就是为什么 virtual 继承会带来4字节的额外负担 )
( 注: 如果一个类 即是虚拟继承 内部又包含虚函数, 那么他应该有两根指针 virtual base class ptr, virtual table ptr )

//*********************************************************************************************//

---> "对象成员的效率":
对于数据封装性来说:
-> 单纯的数据;
-> 数组;
-> 结构;
-> 类内联;
-> 类成员;

如果我们对以上类型进行分析, 则会发现: "在优化之后 他们的效率相同";
结论:"封装不会带来额外的负担";

对于数据继承性来说:
-> 单一继承;
-> 虚拟继承( 单层 );
-> 虚拟继承( 多层 );

如果我们对以上继承进行分析, 则会发现: "在优化之后, 他们效率 开始下降";
结论:"单一继承( 不管层数 ) 不会带来额外负担, 虚拟继承 会带来额外的负担, 而且随着继承深度加深 效率越来越低";

//*********************************************************************************************//

ssm框架搭建 这个是一个在idea上成功跑起来的ssm框架项目,保存在这里方便以后使用直接下载 立即下载

相关推荐

Anaconda离线创建python环境

既然是离线创建python环境,就需要有一个已经创建好的python环境。所以我们有两台win10的机器,分别是A和B。两台机器都安装了anaconda。其中A可以连网,因此我们在A上创建好一个python2.7的环境py27,然后将py27移植(安装)到B上。B连不连网都无所谓。 一、机器上A上创建python2.7的环境py27 有两种方法: 方法1:使用Anaconda的图形界面。首先,点击Environments->Create,然后输入要创建的环境名称"py27",然后选择2.7,如图

FY_2018的博客 6787

探究c++对象模型之data语义学(一)

c++标准中有这样一个规定:   "no object shall have thesame address in memory as any other variable".   由此规定,导致几乎所有的编译器对一个空类都会添加一个char。   那什么是一个空类呢:   ·Has static members /member function   ·Has no vir

aoumeior的博客 512

究竟什么是虚拟同步机???虚拟同步机巨简单理解

同步发电机定子铁芯的内圆均匀分布着定子槽,槽内按一定规律嵌放着对称的三相绕组U1-U2、V1-V2、W1-W2,如图1所示。工作原理转子铁芯上装有制成一定形状的成对磁极,磁极上绕有励磁绕组。励磁绕组上通直流电时,会在电机的气隙中形成极性相间的分布磁场,称为励磁磁场。当原动机拖动转子以恒定速度旋转时,励磁磁场随转轴一起旋转并顺次切割定子各相绕组。定子电枢绕组中将会感应出大小和方向周期性变化的三相对称正弦感应电动势。各相电动势大小相等,相位各差120°。

weixin_53126442的博客 2607

通过对象指针的方式强行指定到子类_c++对象模型

使用c++有些年头了,有一本深度搜索c++对象模型的书写的很赞,很经典。本文是本书的读书笔记。关于对象加上封装后的布局成本c语言中如下声明一个结构体typedef struct point3d{ float x; float y; float z;}Point3d;struct point3d 转化为class Point3d之后class Point3d{ public: Point3d(flo...

weixin_39517289的博客 94

MATLAB机械臂轨迹规划:在关节空间中生成多项式轨迹以及 jtraj函数(内容超详细讲解)

matlab机器人仿真,关节空间多项式轨迹生成

qq_40969179的博客 1万+

I2C通信协议SCL与SDA引脚特性:核心要点总结

深入讲解I2C通信协议中SCL和SDA引脚的工作机制与电气特性,帮助理解i2c通信协议的稳定传输原理,掌握上拉电阻配置与信号时序控制要点。

weixin_42103128的博客 2737

深度搜索C++对象模型 - 构造语义学

 深度搜索C++对象模型:  构造,拷贝,析构语义学 //*********************************************************************************************// ---> "构造函数语义学": class A {     public:     virtual ~A() = 0;     v

github_21089181的专栏 473

UVM环境复位--stop_sequences()

在UVM验证环境中, stop_sequences是一个用于强制终止所有正在运行的 Sequence 的方法,通常用于动态控制激励生成流程。1.通过uvm_config_db传递事件和严格的同步机制,此方案符适用于复杂复位场景和动态测试控制。组件耦合:Driver 和 Sequence 不再直接依赖env,通过标准接口通信。竞争条件:确保 Driver 完成清理后再终止 Sequence。代码健壮性:使用非阻塞操作和事件监听,避免死锁。

qq_42779035的博客 3014

深度搜索C++对象模型(理念总结)

1. 目标: C++的语法规格(C++ 标准)如何具体实现出来的, 即编译器如何理解并构建一系列的数据结构, 去扩充/优化/翻译cpp源代码,然后组成串行指令,确保最终代码能够准确而高效执行. 大致包括1). 编译器功能的思考和设计逻辑                         2).cpp源代码的编译+链接(不用生成汇编)的步骤. 2.构造函数语义学: 遵循语意(C++ 标准

noticmp的专栏 769

全国30米分辨率逐年植被覆盖度(FVC)数据集

植被覆盖度是描述地表植被的重要参数与生态环境的基本指标,在大气圈、土壤圈、水圈和生物圈中都占据着重要的地位,区域及全球范围的植被覆盖度估算对植被及相关领域的研究具有重要意义。往往参照《土壤侵蚀分类分级标准》,将植被覆盖度划分为4个等级:<30%为低覆盖度、30%—45%为中低覆盖度、45%—60%为中覆盖度、>60%为高覆盖度。本数据集包括1986至2022年间,全国植被覆盖度数据,FVC范围值为0-1,数据为浮点型,GeoTIFF格式。NDVImax 和NDVImin分别为区域内最大和最小的NDVI值。

地球资源数据云的官方博客 1966

基于RK3588的YOLOv11目标检测NPU加速系统设计与实现——模型转换(RKNN)、量化与板端部署全流程(含环境搭建与疑难解析)

而RK3588芯片则是一款性能强劲的边缘计算芯片,将YOLOv11部署在RK3588上,可实现本地化的智能检测应用,比如工业质检中的产品缺陷识别、安防领域的异常行为监测等。比如,优化模型的推理速度,可通过调整模型的输入尺寸、使用更高效的推理框架等方式实现;可以使用RK提供的量化工具来完成这一过程,按照工具的使用说明,对ONNX模型进行量化,生成适用于RK3588的模型文件。现在,你已经掌握了从环境搭建到模型部署的全流程,赶快动手实践,让YOLOv11在RK3588上绽放智能光彩,打造属于你的AI应用吧!

m0_71589036的博客 45

对象传参_c++对象模型

使用c++有些年头了,有一本深度搜索c++对象模型的书写的很赞,很经典。本文是本书的读书笔记。关于对象加上封装后的布局成本c语言中如下声明一个结构体typedef struct point3d{ float x; float y; float z;}Point3d;struct point3d 转化为class Point3d之后class Point3d{ public: Point3d(flo...

weixin_32821643的博客 180

YOLOv11模型压缩技术全面对比:剪枝、量化、蒸馏的原理与实战

YOLOv11模型压缩技术综述 模型压缩技术是解决计算资源受限环境下部署深度学习模型的关键。本文系统介绍了YOLOv11模型压缩的三种核心技术:剪枝、量化和蒸馏。剪枝技术通过移除冗余参数实现模型轻量化,包括结构化剪枝(通道/卷积核剪枝)和非结构化剪枝;量化技术通过降低数值精度(如FP32→INT8)减少存储和计算量;蒸馏技术则利用教师模型指导学生模型训练,在保持精度的同时减小模型规模。三种技术可单独或组合使用,在工业质检、智慧安防等边缘计算场景中发挥重要作用,使YOLOv11在保持80%精度的同时减少70%

本博客聚焦 YOLOv11 全流程落地,涵盖架构优化、数据集处理、训练技巧与多场景部署,兼及国产数据库、Java 开发与 AI 模型应用,内容兼顾理论与工程实践,为开发者提供系统干货,助力高效提升技术能力。 579

深度搜索C++对象模型 - 函数语义学

 深度搜索C++对象模型:  Function Semantics C++支持三种类型的 member function: static nonstatic virtual; 后文分析他们的差异 //*********************************************************************************************//

github_21089181的专栏 543

霍尼韦尔SoftMaster使用说明

霍尼韦尔SoftMaster使用说明

STM32F407中文手册

STM32f407中文手册 本参考手册面向应用开发人员,提供有关使用 STM32F405xx/07xx、STM32F415xx/17xx、 STM32F42xxx 和 STM32F43xxx 微控制器存储器与外设的完整信息。STM32F405xx/07xx、STM32F415xx/17xx、STM32F42xxx 和 STM32F43xxx 构成一个微 控制器系列,各产品具有不同的存储器大小、封装和外设。有关订购信息以及器件的机械与电气特性,请参见数据手册。有关 ARM Cortex™-M4F 内核的信息,请参见《Cortex™-M4F 技术参考手册》。

深度搜索C++对象模型2.2 构造函数语义学-Copy Constructor的构造操作

Shallow Copy = Bitwise Copy,Deep Copy = Memberwise Copy.

春秋战车 1066

华为的C语言编程规范.pdf

华为技术有限公司内部技术规范。本规范制定了编写C语言程序的基本原则、规则和建议。从代码的清晰、简洁、可测试、安全、程序效率、可移植各个方面对C语言编程作出了具体指导。

深挖C++:类和对象(中)

(先进后出)

xys_678的博客 242

OV9734 DATASHEET,完整规格书

OV9734完整规格书,包括电气参数,尺寸规格,寄存器配置表等

C++移动构造函数详解

移动构造函数是C++11引入的一种特殊构造函数,用于从临时对象(右值)"窃取"资源来初始化新对象,而不是进行昂贵的深拷贝。char* data;public:// 移动构造函数:参数是右值引用 &&// 关键:把源对象的资源置空。

拒绝AI文,努力在AI时代写出感动人心的好文章 391

ThunderKittens 深度解析:一个不基于 MLIR 的 C++ 模板 GPU DSL

Triton 是"让更多人能写 GPU kernel",ThunderKittens 是"让会写的人写得更爽"。前者用 MLIR 换易用性,后者用 C++ 模板换可控性。它们不是替代关系,而是覆盖了 GPU 编程光谱的两端。ThunderKittens 的出现,本质上是对"GPU DSL 必须基于 MLIR"这一默认假设的挑战。编译期类型系统本身就可以是一个强大的 DSL 基础设施,不需要中间 IR,不需要黑盒 pass,也能实现 tile 级抽象和零运行时开销。

Maxwell_Newton的博客 339

跟我学c++中级篇—类型定义的方式

本文系统阐述了编程中类型定义的重要性及c++中的实现方式。重点对比了宏定义、typedef与modern using三种机制,指出using在可读性、灵活性和模板支持上的优势,推荐优先使用。同时提醒开发者注意别名滥用、类型歧义、错误信息冗长等问题,强调统一规范与合理设计。最终结论:在现代c++开发中,应以using为主,兼顾简洁性与可维护性,避免陷入命名混乱与编译困境。

fpcc的专栏 71

【C语言】字符与字符串函数

C语言中字符串为以\0结尾的字符数组,标准库函数基于此约定。本文解析字符串内存布局,详解ctype.h与string.h中字符分类、长度计算、拷贝、比较等函数的使用要点,强调长度判断与越界风险,最后通过命令行待办事项示例整合fgets、sscanf、strncpy、strcmp,展示实际应用中的关键细节。

记录在学习过程中学到的知识 347

C++ 函数模版

模板参数:● template ,T 就是类型占位符,名字可以自定义,习惯用T● 占位符可以在函数返回值、形参、函数内部当作类型使用使用要点模板代码一般写在头文件:编译器需要看到完整模板源码,才能在每个编译单元完成实例化全局函数、类内成员函数都可以写成模板实例化发生在编译阶段,不是运行时隐式实例化:调用时编译器自动推导实参类型,生成对应版本函数。

2501_94041724的博客 304

C++ 运行时多态与虚函数机制全面剖析【面试重点】

构成C++ 运行时多态必须是基类的指针或者引用调用虚函数。被调用的函数必须是虚函数,并且派生类必须对该虚函数完成重写/覆盖(Override)。只有基类的指针或引用才能既指向基类对象,又指向派生类对象(切片机制);而只有完成了虚函数重写,派生类与基类才具备不同的函数行为,达到“指向谁就调用谁”的效果。在类成员函数的前面加上virtual关键字修饰,该成员函数就成为了虚函数。public:// 成员函数前加 virtual 修饰,声明为虚函数。

Fuyo_0209的博客 437

#SQLite 数据库笔记一:(概念 / 终端指令 / SQL 语句 / C 编程 / 回调函数)

数据库 = 数据的仓库,假设数据是海量。能力说明存储数据持久化保存,程序退出数据还在统计数据、分组、排序数据管理增、删、改、查(CRUD)嵌入式设备上也会用数据库(单片机网关、路由器、工业 HMI 都常见),因为 sqlite 体积小、无需服务进程、单文件即可。数据库 = 库 > 表 > 记录(行) > 字段(列)sqlite3 = 开源、C 写的、单文件、免安装、最多 2T 的嵌入式关系型数据库。

lwq20051110的博客 213

C 语言 malloc() 详解与实战 Demo

本文详解C语言malloc()函数,涵盖其语法、内存原理及实战应用。通过动态整数、数组、结构体与链表的Demo,演示如何安全申请、使用与释放内存,强调避免内存泄漏与空指针检查的重要性,帮助开发者掌握动态内存管理核心技能。

tangPHP的博客 372

【C++ 基础入门】类和对象(上):封装、对象模型与 this 指针

C++类与对象知识(面向过程和面向对象的初步认识,类的初步认识,类的访问限定符及封装,类的作用域、实例化,类的对象模型,this指针)

2601_96587588的博客 885

【C++ 基础入门】C++继承(下):问题、底层原理与组合

C++继承(菱形继承的问题、虚继承原理、继承与组合、构造顺序)

2601_96587588的博客 791
上一篇: 深度搜索C++对象模型 - 函数语义学
下一篇: 深度搜索C++对象模型 - 构造语义学
zhang_yao_wu1993
博客等级 码龄12年 0粉丝 18原创
评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

个

红包个数最小为10个

元

红包金额最低5元

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

抵扣说明:

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

余额充值