这可能是一个非常愚蠢的问题,但无论如何我会问.我很好奇对象在内存中的样子.显然,它必须包含其中的所有成员数据.我假设对象的函数不会在内存中重复(或者我错了?).在内存中拥有999个对象并且反复定义相同的功能似乎很浪费.如果内存中只有1个函数用于所有999个对象,那么每个函数如何知道要修改的成员数据(我特别想知道低级别).是否有一个对象指针被发送到幕后的函数?也许每个编译器都有所不同?
另外,static关键字如何影响这个?使用静态成员数据,我认为所有999个对象都将使用完全相同的内存位置作为其静态成员数据.这存储在哪里?静态函数我想它也只是内存中的一个位置,并且不必与实例化对象进行交互,我认为我理解.
ten*_*our 21
静态类成员的处理方式几乎与全局变量/函数一样.因为它们没有绑定到实例,所以没有什么可以讨论内存布局.
您可以想象,每个实例都会复制类成员变量,因为每个实例都可以为每个成员变量拥有自己的唯一值.
类成员函数仅在内存中的代码段中存在一次.在较低的层次上,它们就像普通的全局函数一样,但它们会收到一个指针this.使用x86上的Visual Studio,它通过ecx寄存器使用thiscall调用约定.
在谈论虚函数,多态时,内存布局变得更加复杂,引入了一个" vtable ",它基本上是一组定义类实例地形的函数指针.
你在这里问了几个问题......
布局
所有非静态成员都在内存中组织,就像结构一样.如果编译器选择放入任何内容,可能会有填充.如果你有一个对象数组,它就像一个结构数组
静态成员
显然是分开存放的.一份.
函数调用
课程幕后有一点魔力.当你调用一个成员函数时,它就像任何其他函数一样,除了它有不同的调用约定.实际上,这会将对象的指针(this)插入参数列表中.
[ 编辑:函数本身的代码不与您的对象一起存储 - 这允许您做有趣的事情,delete this并继续执行成员函数,前提是您不再访问刚删除的对象].
当你有重载或多态函数时,事情会变得更加神奇. 这篇文章解释说我在大约5秒内搜索了一下.我相信还有更多.我从不关心对象调用的内部,但知道它总是很好.
你应该尝试制作一个展示所有这些不同方面的课程,并观察每个案例中产生的装配.在调整一些时间关键代码之前,我已经做过了.
您怀疑,数据成员(字段)是按顺序排列的。这也包括基类的字段。
如果该类(或其基类之一)包含任何虚拟方法,则布局通常以vptr开头,即指向虚拟表(或vtable)的指针,该虚拟表是与该类相关的函数实现的指针表。请注意,这不是标准定义的,但是AFAIK当前所有的编译器都使用这种方法。此外,通过多重继承,它变得更加毛茸茸,因此暂时不考虑它。
+-----------+
| vptr | pointer to vtable which is located elsewhere
+-----------+
| fieldA | first member
| fieldB | ...
| fieldC |
| ... |
+-----------+
Run Code Online (Sandbox Code Playgroud)
字段可能会占用更多空间,而不是它们各自大小的总和,这取决于打包(例如1字节的打包可确保没有间隙,但就性能而言,其效率低于4或8字节的打包)。
成员函数(非静态)通常通过x86体系结构上的ecx寄存器接收指向对象的指针。该标准也未定义。
静态函数与全局函数相似,并且它们在数据段中的静态类字段(对于类的所有实例共享)上运行。