对象的内部表示
所以一直以来我都认为,当您执行类似 ObjectA.field1 之类的操作时,ObjectA 就像堆栈上的任何值一样,您基本上可以访问它的字段。现在我正在浏览有关 OOP 语言的课程的笔记,并意识到当您执行 ObjectA.field1 时,实际发生的是 HEAP(ObjectA 的地址)(field1),它返回 field1 的值。这让我有点困惑。谁能告诉我们为什么尽管我们已经有了对象的值还要进行查找?希望我能够解释一下..
So all this time I thought that when you do something like ObjectA.field1, ObjectA is just like any value on the stack and you basically access its fields. Now I was going through the notes for a class about OOP languages and realized that when you do ObjectA.field1 what actually happens is HEAP(Address of ObjectA)(field1) which returns you the value of the field1. This makes me a bit confused. Can anyone tell why there is a look up going on although we already have the value of the object? Hope I was able to explain..
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(2)
物体其实并没有那么神奇。本质上,一个对象仅由其所有成员的线性集合组成,成员周围有未指定的填充量。从布局角度来看,C++ 类本质上就像 C 结构体:
暂时忽略成员函数和静态变量,可能会这样布局:
Foo
类的每个对象都像这样存储在内存中。我们唯一需要的额外数据是静态成员、成员函数和静态成员函数。静态成员只是全局变量。因此,我们只有一个全局变量:
接下来,静态成员函数只是普通的自由函数:
最后,成员函数:这些本质上是也只是普通函数,尽管有一个额外的参数允许它们查找实例成员:
唯一重要的区别是您无法获得指向成员函数的普通自由函数指针,因为实现函数的实际名称没有公开。引用
Foo::bar()
的唯一方法是通过成员函数指针void (Foo::*ptfm)() = &Foo::bar< /代码>。成员对象稍微简单一些:您可以获取指向它们的普通指针,例如
Foo x; int * p = &xa;
,但您也可以形成一个指向成员的指针:int Foo::*ptm = &Foo::a;
。然后,如果我们有对象
Foo x, y, z;
,我们可以使用实例指针Foo * pi = &x;对 > 和成员指针
int &Foo::* ptm = &Foo::a
或void (Foo::*ptfm)() = &Foo::bar
> 访问给定的相关成员实例:分别是整数pi->*ptm
和函数调用(pi->*ptfm)()
。 (是的,->*
是一个运算符。)(函数指针的免费版本不可能存在,因为多态(虚拟)函数需要比简单的固定函数指针更复杂的调度机制。 )
Objects aren't really that magical. Essentially, an object just consists of a linear collection of all its members, with unspecified amounts of padding surrounding the members. Layout-wise, a C++ class is essentially like a C struct:
Ignoring member functions and statics for now, this might be laid out like this:
Every object of class
Foo
is stored like this in memory. The only extra data we need are the static members, member functions, and static member functions.Static members are just global variables. So we have only one global variable:
Next up, static member functions are just ordinary, free functions:
Finally, member functions: these are essentially also just ordinary functions, though with an extra parameter that allows them to find instance members:
The only important difference is that you cannot obtain an ordinary free function pointer to member functions, since the actual name of the implementation function is not exposed. The only way to refer to
Foo::bar()
is via a pointer-to-member-functionvoid (Foo::*ptfm)() = &Foo::bar
. Member objects are a bit simpler: you can either obtain a normal pointer to them, likeFoo x; int * p = &x.a;
, but you can also form a pointer-to-member:int Foo::*ptm = &Foo::a;
.Then, if we have objects
Foo x, y, z;
, we can use the pairs of instance pointerFoo * pi = &x;
and member pointersint &Foo::* ptm = &Foo::a
orvoid (Foo::*ptfm)() = &Foo::bar
to access the relevant member of the given instance: the integerpi->*ptm
, and the function call(pi->*ptfm)()
, respectively. (Yes,->*
is an operator.)(A free version of the function pointer cannot exist, because polymorphic (virtual) functions require a more complicated dispatch mechanism than a simple, fixed function pointer.)
要获取某些
ClassA
的某些ObjectA
的field1
,计算机必须拥有包含ObjectA
的内存区域的地址>,它知道(静态)field1
(ClassA
)的偏移量(以字节为单位),因此它可以通过添加该偏移量来检索field1
到ObjectA
的地址。To get the
field1
of someObjectA
of someClassA
the computer has to have the address of the memory zone containingObjectA
, it knows (statically) the offset (in bytes) forfield1
(ofClassA
) so it can retrieve thefield1
by adding that offset to the adress ofObjectA
.