您的位置:首页 > 编程语言 > C语言/C++

【深度探索c++对象模型】关于对象

2014-07-04 11:04 381 查看
成员函数虽然包含在类的声明之内,却不出现在对象中。每个非inline成员函数只会诞生一个函数实例。创建对象不会为成员函数分配空间,成员函数放在代码段,多个对象共享。

一、C++对象模型

nonstatic data members被配置于每一个class object之内,static data members则被存放在所有的class object之外。static 和nonstatic function members也被放在所有的class object之外,virtual function则以两个步骤支持之:

1.每一个class产生一堆指向virtual function的指针,放在virtual table中

2.每一个class object被添加了一个指针vptr,指向相关的virtual table,vptr的设定和重置都由每一个class的constructor,destructor和copy assignment运算符自动完成。

c++对象模型主要缺点是,如果应用程序代码本身未曾改变,但所用到的类对象的nonstatic数据成员有所修改,那么那些应用程序代码同样得重新编译

策略性正确的struct

把单一元素的数组放在一个struct的尾端,于是每个struct对象可以拥有可变大小的数组:

struct mumble
{
/*stuff*/
char pc[1];
};
//String是某个字符串,申请一块内存空间,大小为结构体大小加上string这种数据的大小再加一个字节作为安全区
struct mumble *pmumbl = (struct mumble*)malloc(sizeof(struct mumble) + sizeof(string)+1);
//把string的数据拷贝到结构体里pc[0]为起始位置的一片区域里
strcpy(pmumbl->pc, String);


在网络传输、文件读取或其他什么特殊用途里,会用到一些特殊的结构体,这种结构体的特征是,其开始某部分的数据是固定用途,比如传输数据的大小和类型等控制命令,而后续的数据的长度和类型是变动的。
这个“变长”结构体就如问题中的(为了说明就稍加修改):

struct Hd  {
//这里放入头部信息
int type;//后面携带数据的类型
//这里就是携带的数据
char pc[1];
};


而c++中凡处于同一个access section的数据,必定保证以其声明顺序出现在内存布局当中。然而被放置在多个access section中的各笔数据,排列顺序就不一定了。

二、对象的差异

表现一个class object 需要的内存:

1.其nonstatic members的总和大小

2.加上任何由于alignment的需求而填补上去的空间(将数值调整到某数的倍数)(边界调整填补上的空间)

3.加上为了支持virtual而由内部产生的任何额外负担(vptr)

结构体中每个成员的地址是该成员对齐大小的整数倍,整个结构体大小是最大成员对齐大小的整数倍

一个指针或引用,不管它指向哪一种数据类型,指针本身所需的内存大小是固定的。指针类型用于教导编译器如何解释某个特定地址中的内存内容及其大小。

指针的类型

一个指针,不管它指向哪一种数据类型,指针本身所需的内存大小是固定的。指向不同类型之各指针间的差异,既不在其指针表示法不同,也不在其内容(代表一个地址)不同,而是在其所寻址出来的object类型不同。也就是说,指针类型会教导编译器如何解释某个特定地址中的内存内容及其大小

一个类型为void*的指针只能够持有一个地址,而不能通过它操作所指对象的原因:无类型,编译器无法得知对象所占内存大小

class bear:public zooAnimal{...}

bear b;

zooAnimal *pz=&b;

bear *pb=&b;

pz,pb都指向bear object的第一个字节,差别是:pb所涵盖的地址包括整个bear object,而pz所涵盖的地址只包含bear object中的zooAnimal subobject。所以父类指针指向派生类对象,该指针不能操作派生类中独立的数据成员。

当一个base class object被直接初始化为一个派生类对象时,派生类对象会被切割塞入较小的base type内存中,于是多态不再呈现
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: