Internal representation of objects

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 get access to its fields. Now I was looking through the notes for the class about OOP languages ​​and realized that when you do ObjectA.field1, HEAP (Address of ObjectA) (field1) actually happens, which returns you the value of field1. It bothers me a bit. Can someone tell me why the search occurs, although we already have the value of the object? Hope I could explain.

+3
source share
2 answers

Objects are not really magical. In fact, an object consists only of a linear set of all its members with an indefinite number of additions surrounding the members. Layout, a C ++ class is essentially similar to 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 at the moment can be done as follows:

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

Each object of class Foo stored in memory in this way. The only additional data we need is static elements, member functions, and static member functions.

Static elements are just global variables. Thus, we have only one global variable:

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

Next, static member functions are regular, free functions:

 void static__Foo__car() { } 

Finally, member functions: these are essentially also ordinary functions, but with an additional 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 get a regular pointer to a free function for member functions, since the actual name of the implementation function is not displayed. The only way to access Foo::bar() is through the member function void (Foo::*ptfm)() = &Foo::bar . Member objects are a bit simpler: you can get a normal pointer to them, for example Foo x; int * p = &x.a; Foo x; int * p = &x.a; , but you can also form a member-to-pointer: int Foo::*ptm = &Foo::a; .

Then, if we have objects Foo x, y, z; , we can use instance pointer pairs Foo * pi = &x; and member pointers int &Foo::* ptm = &Foo::a or void (Foo::*ptfm)() = &Foo::bar to access the corresponding member of this instance: integer pi->*ptm , and function call (pi->*ptfm)() , respectively. (Yes, ->* is the operator.)

(A free version of a function pointer cannot exist, because polymorphic (virtual) functions require a more complex dispatch mechanism than a simple, fixed function pointer.)

+7
source

To get field1 some ObjectA some ClassA , the computer must have a memory zone address containing ObjectA , it knows the (statically) offset (in bytes) for field1 (from ClassA ) to get field1 by adding this offset to the address of ObjectA .

+3
source

Source: https://habr.com/ru/post/1386370/


All Articles