对象的内部表示

发布于 2024-12-17 04:17:53 字数 223 浏览 3 评论 0原文

所以一直以来我都认为,当您执行类似 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 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(2

青巷忧颜 2024-12-24 04:17:53

物体其实并没有那么神奇。本质上,一个对象仅由其所有成员的线性集合组成,成员周围有未指定的填充量。从布局角度来看,C++ 类本质上就像 C 结构体:

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

  static long q;

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

暂时忽略成员函数和静态变量,可能会这样布局:

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

Foo 类的每个对象都像这样存储在内存中。我们唯一需要的额外数据是静态成员、成员函数和静态成员函数。

静态成员只是全局变量。因此,我们只有一个全局变量:

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

接下来,静态成员函数只是普通的自由函数:

void static__Foo__car() {  }

最后,成员函数:这些本质上是也只是普通函数,尽管有一个额外的参数允许它们查找实例成员:

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

唯一重要的区别是您无法获得指向成员函数的普通自由函数指针,因为实现函数的实际名称没有公开。引用 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::avoid (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:

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

野生奥特曼 2024-12-24 04:17:53

要获取某些ClassA的某些ObjectAfield1,计算机必须拥有包含ObjectA的内存区域的地址>,它知道(静态)field1ClassA)的偏移量(以字节为单位),因此它可以通过添加该偏移量来检索 field1ObjectA的地址。

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.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文