Internal representation of objects

谁说我不能喝 提交于 2019-12-01 23:52:43

问题


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..


回答1:


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:

struct Foo {
  int a;
  char b;
  std::string s;

  static long q;

  void bar() { print(s); log(a); }
  static void car() { }
}

Ignoring member functions and statics for now, this might be laid out like this:

+= class Foo =+
+-------------+  ---\   <---   Foo * p
|  int        |     s
+-------------+     i
|  char       |     z
+-------------+     e
| <padding>   |     o
+-------------+     f
| std::string |    (F
+-------------+     o
| <padding>   |     o)
+-------------+  ---/

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:

+== static__Foo__q ==+
+--------------------+
|  long int          |
+--------------------+

Next up, static member functions are just ordinary, free functions:

void static__Foo__car() {  }

Finally, member functions: these are essentially also just ordinary functions, though with an extra parameter that allows them to find instance members:

void member__Foo__bar(Foo * p) { print(p->s); log(p->a); }

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-function void (Foo::*ptfm)() = &Foo::bar. Member objects are a bit simpler: you can either obtain a normal pointer to them, like Foo 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 pointer Foo * pi = &x; and member pointers int &Foo::* ptm = &Foo::a or void (Foo::*ptfm)() = &Foo::bar to access the relevant member of the given instance: the integer pi->*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.)




回答2:


To get the field1 of some ObjectA of some ClassAthe computer has to have the address of the memory zone containing ObjectA, it knows (statically) the offset (in bytes) for field1 (of ClassA) so it can retrieve the field1 by adding that offset to the adress of ObjectA.



来源:https://stackoverflow.com/questions/8196833/internal-representation-of-objects

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!