关于对象

超越基础轮廓:用Unity Shader Graph可视化打造可交互的动态外发光效果 本文详细介绍了如何利用Unity Shader Graph创建可交互的动态外发光效果,从基础轮廓到复杂的交互响应。通过可视化节点编辑,开发者可以轻松实现顶点偏移、菲涅尔效应和动态参数控制,打造专业级的游戏视觉反馈,显著提升玩家沉浸感和开发效率。 阅读详情


一、C++对象模型

在C++中,有两种数据成员:static和nonstatic,以及三种成员函数:static、nonstatic和virtual。已知下面这个类point声明:

在这里插入图片描述

怎样在机器中表现这个类point呢?

1.1、简单对象模型

在简单对象模型中,一个object是一系列的slots,每一个slot指向一个成员。成员按其声明顺序,各被指定一个slot。每一个数据成员或函数成员都有自己的一个slot。

在这里插入图片描述

在这个简单模型下,成员本身并不放在object中。只有"指向成员的指针"才放在object内。这么做可以避免"成员有不同的类型,因而需要不同的存储空间"所招致的问题。object中的成员是以slot的索引来寻址的。

虽然这个模型并没有被应用于实际产品上,不过关于索引或slot个数的观念,被应用到C++的"指向成员的指针"(pointer to member)观念之中。

1.2、表格驱动对象模型

为了对所有类的所有对象都有一致的表达方式,表格驱动对象模型把所有与成员相关的信息抽出来,放在一个数据成员表和一个成员函数表中,类对象本身则内含指向这两个表格的指针。

在这里插入图片描述

虽然这个模型也没有实际应用于真正的C++编译器身上,但成员函数表这个观念却成为支持虚函数的一个有效方案。

1.3、C++对象模型

Stroustrup当初设计(目前仍占有优势)的C++对象模型是从简单对象模型派生而来的,并对内存空间和存取时间做了优化。在此模型中,nonstatic数据成员被配置于每一个类对象之内,static数据成员则被存放在类对象之外。static和nonstatic成员函数也被放在类对象之外。虚函数则以两个步骤支持:

  • 1、每一个类产生出一堆指向虚函数的指针,放在表格中,这个表格被称为virtual table(vtbl)。
  • 2、每一个类对象被安插一个指针,指向相关的virtual table。通常这个指针被称为vptr。每一个类所关联的type_info 对象也经由virtual table被指出来,通常放在此表格的第一个slot。

在这里插入图片描述

1.4、对象模型如何影响程序

不同的对象模型,会导致"现有的程序代码必须修改"以及"必须加入新的程序代码"两个结果。例如下面这个函数,其中class X定义了一个copy constructor、一个virtual destructor和一个virtual function foo:

在这里插入图片描述

这个函数有可能在内部被转化为:

在这里插入图片描述

由于类X有两个virtual functions,一个是destructor,一个是foo,所以X对象布局如下:

在这里插入图片描述
在被转化的代码中,px->_vtbl[0]指向X的type_info object,px->_vtbl[1]指向X::~X(),px->_vtbl[2]指向X::foo()。

二、对象的差异

需要多少内存才能够表现一个类对象呢?一般而言要有:

  • 其nonstatic数据成员的总和大小
  • 加上任何由于alignment的需求而填补上去的空间(可能存在于成员之间,也可能存在于集合体边界)
  • 加上为了支持virtual而由内部产生的任何额外负担

2.1、指针的类型

一个指针,不管它指向哪一种数据类型,指针本身所需的内存大小是固定的。例如,有下面的ZooAnimal声明及变量定义:

在这里插入图片描述

其中的类对象za和指针pza的可能布局如下图所示:

在这里插入图片描述

但是,一个指向ZooAnimal的指针与一个指向整数的指针或一个指向template Array的指针有何不同呢?

在这里插入图片描述

以内存需求的观点来说,没有什么不同!它们三个都需要有足够的内存来放置一个机器地址。"指向不同类型之各指针"间的差异,既不在其指针表示法不同,也不在其内容(代表一个地址)不同,而是在其所寻址出来的对象类型不同。也就是说,"指针类型"会教导编译器如何解释某个特定地址中的内存内容及其大小

  • 一个指向地址1000的整数指针,在32位机器上,将涵盖地址空间1000~1003
  • 如果String是传统的8-bytes,那么一个ZooAnimal指针将横跨地址空间1000~1015

那么,一个指向地址1000而类型为void的指针,将涵盖怎样的地址空间呢?答案是不知道!这就是为什么一个类型为void的指针只能够持有一个地址,而不能够通过它操作所指对象的缘故。

2.2、加上多态

现在,让我们定义一个Bear,作为一种ZooAnimal。有如下类型定义和变量定义:

在这里插入图片描述

无论是pointer或reference都只需要一个word的空间(在32位机器上是4-bytes)。b、pb、rb的布局如下图所示。Bear object需要24bytes,也就是ZooAnimal的16bytes加上Bear所带来的8bytes。

在这里插入图片描述

假设我们的Bear object放在地址1000处,一个Bear指针和一个ZooAnimal指针有什么不同呢?

在这里插入图片描述

它们每个都指向Bear object的第一个byte。其间的差别是,pb所涵盖的地址包含整个Bear object,而pz所涵盖的地址只包含Bear object中的ZooAnimal subobject

除了ZooAnimal subobject中出现的成员,不能够使用pz来直接处理Bear的任何成员。唯一例外是通过virtual机制。

多态所造成的"一个以上的类型"的潜在力量,并不能够实际发挥在"直接存取objects"这件事情上,比如,将一个派生类对象赋值给一个基类对象时,派生类对象将会被切割以塞入较小的基类类型内存中。有一个似是而非的观念:面向对象程序设计并不支持对对象的直接处理。举个例子,下面这组定义:

在这里插入图片描述

其可能的内存布局如下图所示:

在这里插入图片描述

将za或b的地址,或pp所含的内容(也是个地址),指定给pza,显然不是问题。一个pointer或一个reference之所以支持多态,是因为它们并不引发内存中任何"与类型有关的内存委托操作(type-dependent commitment)";会受到改变的,只有它们所指向的内存的"大小和内容解释方式"而已。

浅谈一下JAVA对象对象引用以及对象赋值 浅谈一下JAVA对象对象引用以及对象赋值 今天有班级同学问起JAVA对象的引用是什么。正好趁着这次机会,自己总结一下JAVA对象对象引用以及对象赋值。自己总结了所看到的网上相关方面的不少帖子,整理汇总形成下面的文章。 Java对象及其引用 初学Java,总是会自觉或不自觉地把Java和C++相比较。在学习Java类与对象章节的时候,发现教科书和许多参考 阅读详情

相关推荐

理解js对象,js对象分类:内置对象(单体内置对象、基本包装对象)、宿主对象、自定义对象

一、什么是对象 1.js中将对象描述成一组无序属性的集合,其属性值可以包含基本值、对象或者函数(当属性值为函数时我们便叫它方法),只有对象才有属性和方法; 属性集合:无非就是一组名(也叫键)值对,每个属性名都映射到一个值,也有人叫散列、散列表、字典、关联数组…; 无序:即js对象的属性排列没有顺序,会因浏览器而异; 2.javascript中除了null、undefined、string、numb...

weixin_45471827的博客 1590

C++对象模型】| 【01】简单了解C++对象模型的布局

文章目录1、class加上封装后的布局成本2、C++对象模式2.1 简单对象模型2.2 表格驱动对象模型2.3 C++对象模型2.4 对象模型如何影响程序2.5 struct与class的差异2.6 面向对象模型中的多态 1、class加上封装后的布局成本 C++在布局或存取时间上的额外负担是由virtual引起的; - 虚函数机制,支持一个有效率的执行期绑定; - 虚基类,有一个单一而被共享的实例; 当然继承也会给该子类增加额外负担; 2、C++对象模式 在class中分为: 数据成员:静态、非静态

weixin_45926547的博客 1164

C++对象,堆对象,静态对象的理解

对象 的优势是在适当的时候自动生成,又在适当的时候自动销毁,不需要程序员操心;而且栈对象的创建速度一般较堆对象快,因为分配堆对象时,会调用operator new操作,operator new会采用某种内存空间搜索算法,而该搜索过程可能是很费时间的,产生栈对象则没有这么麻烦,它仅仅需要移动栈顶指针就可以了。但是要注意的是,通常栈空间容量比较小,一般是1MB~2MB,所以体积比较大的对象不适合在栈中分配。特别要注意递归函数中最好不要使用栈对象,因为随着递归调用深度的增加,所需的栈空间也会线性增加,当所需栈空

流楚丶格念的博客 5023

《深度探索C++对象模型》读书笔记第一章:关于对象

《深度探索C++对象模型》读书笔记之 关于对象 前言 c语言中,“数据”和“处理数据的操作(函数)” 是分开声明的,将这种程序方法称为程序性(procedural),比如声明一个struct Point3d: struct Point3d { float x; float y; folat z; }; 而操作该数据数据的函数例如打印函数,只能另外定义成: vo...

yhcuac 2427

c++对象模型

一、什么是c++对象模型 语言中直接支持面向对象程序设计的部分。 对于各种支持的底层实现机制。 二、c++对象的布局成本 成员函数不占用成本 member functions虽然再class的声明之内,却不在object之中。每一个non-inline member function只会诞生一个函数实例。 每一个“拥有零个或一个定义”的inline function则会在其每一个使用者(模块)身上产生一个函数实例。 c++在布局以及存取时间上主要的额外负担是由virtual引起的 virtual

gb173652770的专栏 2256

C++中不同类型对象的存放位置

C++中不同类型对象的存放位置1. 存储区域2. 不同类型对象的存储2.1 全局对象2.2 局部对象2.3 静态局部对象2.4 动态对象C++中,定义的对象被放在不同的区域中,以下就各个区域以及不同类型对象的存储情况作简要介绍。 1. 存储区域 栈(Stack)是存在于作用域(scope)的一块内存空间。 例如当你调用函数时,函数本身就会形成一个栈用来放置它所接收的参数,以及返回地址。 堆(H...

九霄星河的博客 6372

对象对象的引用

最近初学java对于对象对象的引用以及实例化有诸多迷惑,查了很多博客和API,现整理自己的理解如下:Java是一种面向对象的语言,采用类和对象的概念。Java中每个对象都有一种类型,即对象所属的类。类有两个主要成员:域(field)和方法(method)。域是与一个类或该类的对象相关联的数据的变量。域中存储初值或执行类的方法得到的计算结果。方法包含该类的可执行代码。方法由语句构成。方法被调用的方...

flybone7的博客 1万+

【没对象怎么办?JavaScript-带你找对象对象是什么,对象能干嘛,对象该怎么用,本篇带你了解js中的对象

JavaScript-对象,清晰地阐述了对象是什么,对象能干嘛,如何使用对象对象该在什么时候用

zhaochen1127的博客 1670

到底什么是对象,什么是对象的引用?对象对象的引用有那些区别?

一、分析对象引用与对象的区别 为了接下来进行更好的分析,我先建立一个Demo类,用于后面的分析。 public class Demo{ //默认构造方法 public Demo{ } 接下来,我们用Demo类来创建一个对象。 Demo demo=new Demo(); 这一条语句,其实包括了四个动作: 1)右边的“new Demo”,是以Demo类为模板,在堆空间里创...

无话可说丶 5063

5、js中的内置对象、数学对象、日期对象、数组对象、字符串对象

5、js中的内置对象、数学对象、日期对象、数组对象、字符串对象

m0_58779986的博客 1536

window对象的子对象

window对象(有属性和方法) 特点: window是浏览器宿主对象,与js无关,支持所有浏览器,表示浏览器窗口 所有js的全局对象、全局函数、全局变量都是window对象的成员 注:以下所有属性都可以不需要window前缀,子对象更加详细的属性和方法见另一篇博客: window对象的子对象(属性的一种) 1、window.document ...

qq_42025192的博客 1万+

Window 对象、document对象、history对象、location对象、navigator对象、screen对象

Window 对象 Window 对象 Window 对象表示浏览器中打开的窗口。 如果文档包含框架(frame 或 iframe 标签),浏览器会为 HTML 文档创建一个 window 对象,并为每个框架创建一个额外的 window 对象。 Window 对象集合 集合 描述 frames[] 返回窗口中所有命

ssisse的博客 5531

Cookie对象、Session对象、Request对象、Response对象、Application对象、pageContext对象、Out对象

对象存储位置生命周期作用范围典型用途Request服务器一次请求同一次请求内接收表单参数、请求转发Response服务器一次请求同一次请求内输出响应、重定向、设置 CookieCookie客户端可配置(默认随浏览器)所有请求(带 Cookie 时)记录用户偏好、自动登录Session服务器会话期间(默认 30 分钟)同一用户的连续请求登录状态维持、购物车服务器应用生命周期所有用户、所有请求全局配置、网站访问量服务器单个 JSP 页面。

墨阳的博客 716

对象对象变量

         要想使用对象,就必须首先构造对象,并指定其初始状态。然后对对象应用方法。          在java程序设计语言中,使用构造器构造新实例,构造器是一种特殊的方法,用来构造并初始化对象。下边看一个例子,在java库中包含一个Date类,他的对象将描述一个时间点,例如:“ December 31,1991,23:23:23 GMT”。           构造器的名字应该与类名...

weixin_42630877的博客 5360

mybatis中对象嵌套对象

entity public class BsEnterpriseFinanceYear extends Model<BsEnterpriseFinanceYear> { private BsEnterprise bsEnterprise;//另一个类对象 } Mapper <!-- 通用查询映射结果 --> <re...

XUEH 5654

局部对象和全局对象

c++环境下讨论局部对象和全局对象局部对象全局对象代码展示 局部对象 在语块句中定义的对象称为局部对象,包括函数的形参。局部对象仅在相应的语句块内部可见,而且还会屏蔽外层作用域中的同名对象。 1、自动对象 自动对象的生命期开始于定义语句的执行,结束于作用域的结尾处。 函数形参是自动对象,进入函数时被分配存储空间,函数执行结束时消亡。 对于未初始化的局部对象,值为随机值。 2、局部静态对象 一个函...

Yinan_Zheng的博客 2449

C++之局部对象,全局对象,静态对象

我们常常对于C++当中的局部对象和全局对象的初始化结果不太熟悉,而且还有一个静态对象是什么鬼?下面举例说明 #include<iostream> #include<vector> #include <string> using namespace std; class Dog{ public: int num; string name; }; ...

IT荻的博客 3156

JavaScript对象 BOM对象 及 DOM对象

目录   JavaScript对象 BOM对象 DOM对象 JavaScript对象         js内部的一些语法对象。 其中包括 String对象:处理字符串        Array对象:存储多个值,多种值 Date对象:处理日期和时间 等等 各个对象中都有相应的方法和属性可以使用。 全局函数不基于某个对象,可以在script中直接调用。     BO...

ljq961206的博客 866
上一篇: STL之适配器(adapter)
下一篇: Data语意学
Spring_24
博客等级 码龄11年 46粉丝 41原创
评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

Spring_24

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值