C++对象模型(1)

当我们需要招一个C++工程师的时候,我一般会简单问一下 C++ 的基本概念。比如:static 的作用,const 的作用等。这些基本概念回答完后,我会问几个关于对象模型的问题来评定级别。

有几次突发奇想的问了一下sizeof 的几个问题。

class A
{};
sizeof(A)=?

  这个问题只要了解过的人都知道等于1,如果回答0,那你可能就是一个C++入门不久的人,后续也就不会再问更深入的问题了。

由这个问题会引出别的问题,比如成员函数占用多少空间,成员变量会占用多少空间,虚函数引入之后会占用多少空间。虚拟继承,定义类时的优化等等问题。这些问题会在后续的一系列文章里介绍。

先来个入门的,成员函数和成员变量占用空间的问题。

如果在上面这个类中加入一个成员函数,sizeof 的结果还是1,这说明成员函数不会引入额外的空间占用。

如果在上面这个类中加入一个成员变量,sizeof 的结果会随着变量类型不同而不同。

如果在上面这个类中加入多个成员变量,sizeof 的结果可能会因为顺序的不同而不同。

首先来看,为什么没有任何成员变量时,sizeof 的结果是1而不是0.

  1. 编译器没有在编译的时候提出质疑这中空类不允许存在
  2. 在调用 new 方法的时候,编译器要做两件事,分配内存和调用构造函数(编译器会根据自己的需要,为这个类生成必要的构造函数,这个会在后续的系列中介绍)

这时候问题来了,需要分配多少内存空间呢?如果是0的话,那么是不是应该分配大小为0 的空间呢?这让编译器太为难了吧。怎么能分配空间为0,然后还能保证对象的唯一性呢?(独一无二的地址) 那还是默认给它1,这样我还能正常的工作下去,多了也浪费。这就是为什么需要给空类默认1的空间了。

为什么成员函数不会占用内存空间呢?(非虚函数)

  1. 其实成员函数会占用内存空间的。
  2. 多个对象使用的成员函数是一样的(非虚函数,所以执行的代码是一样的)
  3. 系统为成员函数分配内存,但是所有对象是共享的。
  4. 编译器在编译到调用成员函数的地方,会为成员函数自动加上 this 指针,这样相当于每个对象实例调用成员函数时会有不同的参数

系统只需要为这种非虚函数保留一份内存,而不需要为每个对象实例都分配一块儿内存来浪费空间。

因为各类型所需要的空间不一样,所以成员变量的类型会导致占用空间不同。

为什么有多个成员变量时,顺序可能会影响类的大小呢?

想看一个例子

class A1
{
   char c1;
   int i;
   char c2;
};

class A2
{
    char c1;
    char c2;
    int i;
};

class A3
{
    int i;
    char c1;
    char c2;
};

  这上边的三个不同的类,其成员变量是一样的,我们看看结果怎样:

sizeof(A1) = 12; sizeof(A2) = sizeof(A3) = 8.

为什么不是6呢?第一个类的大小为什么是12呢?第二个和第三个为什么都是8呢?

  1. char 的大小为1
  2. 默认按照4位对齐,不足4位,补0对齐
  3. int 在32位下是4
时间: 2024-11-05 15:44:44

C++对象模型(1)的相关文章

JavaScript----BOM(浏览器对象模型)

BOM 浏览器对象模型 BOM 的全称为 Browser Object Model,被译为浏览器对象模型.BOM提供了独立于 HTML 页面内容,而与浏览器相关的一系列对象.主要被用于管理浏览器窗口及与浏览器窗口之间通信等功能. 1.Window 对象 window对象是BOM中最顶层对象:表示当前浏览器窗口,window对象的属性和方法应用于当前整个浏览器窗口. window 对象的属性主要有: screenX / screenY / screenLeft / screenTop:都为获取位置

C++ 继承、多继承、虚拟继承对象模型

C++面向对象语言一大难点是继承,但又是不得不掌握的.简单的继承是很容易理解的,但是当涉及到多继承,设计到虚函数的继承,特别是涉及到虚继承时,问题就会变得复杂.下面的内容来自参考资料中的三篇文章.C++的继承学习中,最主要是要掌握派生类的对象模型,基类和派生类指针之间的向上向下类型转换,当继承中的出现虚函数成员函数的访问(多态),虚继承是如何通过引入虚基表解决"菱形继承"中存在多份公共基类的问题. 一.简单的对象模型 1.定义 class MyClass { public: int v

第五十课、c++对象模型分析(上)

一.c++对象模型之成员变量 1.class是一种特殊的struct (1).在内存中class依旧可以看做是变量的集合 (2).class与struct遵循相同的内存对齐规则 (3).class中的成员函数和成员变量是分开存储的 A.每个对象有独立的成员变量 B.所有对象共享类中的成员函数 2.运行时的对象退化为结构体的形式 (1).所有成员变量在内存中依次分布 (2).成员变量间可能存在内存间隙 (3).可以通过内存地址直接访问成员变量 (4).访问权限关键字在运行时失效 #include<

第51课 C++对象模型分析(下)

1. 单继承对象模型 (1)单一继承 [编程实验]继承对象模型初探 #include <iostream> using namespace std; class Demo { protected: int mi; int mj; public: //虚函数 virtual void print() { cout << "mi = " << mi << ", " << "mj = " &l

SharePoint服务器端对象模型 之 使用CAML进展数据查询

SharePoint服务器端对象模型 之 使用CAML进行数据查询 一.概述 在SharePoint的开发应用中,查询是非常常用的一种手段,根据某些筛选.排序条件,获得某个列表或者某一些列表中相应的列表条目的集合. 除去列表上的查询之外,在SharePoint中还大量存在着各种各样的查询,比如针对回收站的SPRecycleBinQuery.针对审计的SPAuditQuery.针对变更的SPChangeQuery等等,不过这些查询在实际项目中使用到的频率并不是很高.本章节还是着重介绍列表查询功能.

Selenium2(java)页面对象模型(Page Object) 八

在开发一个 Selenium WebDriver 测试,我们可以使用页面对象模型.这个模型可以使测 试脚本有更高的可维护性,减少了重复的代码,把页面抽象出来.对象模型也提供了一个注释,帮助缓存远程,避免出现元素过期的问题. 分类页面元素 新建java项目selenium_po,导入testng和selenium类库 新建一个page包和一个test包用于存放测试用例 在page包中新建一个BDPage.java用于存取元素 具体代码: package page; import org.openq

C++对象模型

什么是C++对象模型? 要想理解它,必须把C++语言层面的面向对象特征和概念与对象的底层技术结合起来进行分析. 前者如构造函数.拷贝和赋值函数.析构函数.静态成员.虚函数.继承.组合.动态创建对象.RTTI等. 后者则是语言实现隐藏起来的细节,如对象的内存映像,vtable的构造.vptr的插入和初始化的时机.构造和析构函数的自动调用时机.对象的构造和析构次序.临时对象的创建和销毁.RTTI的底层实现技术等. 对象模型参考书籍:<inside The C++ Object Model>

BOM(Browser Object Model) 浏览器对象模型

JavaScript 实现是由 3 个部分组成:核心(ECMAScript),文档对象模型(DOM),浏览器对象模型(BOM) BOM(Browser Object Model) 浏览器对象模型BOM定义了JavaScript进行操作浏览器的各个功能部件的接口,提供访问文档各个功能部件(如窗口本身.屏幕功能部件.框架.浏览历史记录等)的途径以及操作方法.BOM是JavaScript应用中唯一没有相关标准的部分, ,每种浏览器都有其特有的BOM扩展实现. BOM对象 描述Window JavaSc

【C++】深度探索C++对象模型读书笔记--关于对象(Object Lessons)

前言中的内容: 1.什么是C++对象模型? 1.语言中直接支持面向对象程序设计的部分 2. 对于各种支持的底层实现机制 2. C++ class的完整virtual functions在编译时期就固定下来了,程序员没有办法再执行器动态增加或取代其中一个.这使得虚拟调用操作得以快速地派送结果,付出的成本则是执行期的弹性. 3. 全局对象在main()函数之前便完成初始化. 第一章 关于对象 1. 在C++中,有两种class data members:static 和 nonstatic,以及三种

读深入了解c++内核对象模型小结(1/3/4)

之前早就听说这本书不错,如果想对c++进一步的了解可以看看,此书是进阶阶段参考,笔者自己看了书的第一.三.四章节,后面会继续.      第一章讲了c++的对象模型的引入,各种模型的对比和现在c++采用的模型,比如简单对象模型.表格驱动对象模型.C++采用的是针对简单又参考表格驱动既存对象又虚函数存表格之中.有个疑问,成员函数不在对象放在哪?应该是在编译阶段被编译器转化为了外部函数放在了全局区域类似c函数一样,一般是代码段,使用时被动态的加载更多的参考编译器.后面就是讲了c++对象模型oo思想,