带有“this”的类的大小指针

发布于 2024-08-25 13:33:39 字数 214 浏览 7 评论 0原文

即使声明了隐式“this”指针,没有数据成员的类的大小也会返回 1 个字节。返回的大小不应该是 4 个字节(在 32 位机器上)吗?我发现一些文章指出“this”指针不计入计算对象的大小。但我无法理解其中的原因。 另外,如果任何成员函数被声明为 virtual,则类的大小现在返回为 4 个字节。这意味着在计算对象的大小时要对 vptr 进行计数。为什么在计算对象大小时考虑 vptr 而忽略 'this' 指针?

The size of a class with no data members is returned as 1 byte, even though there is an implicit 'this' pointer declared. Shouldn't the size returned be 4 bytes(on a 32 bit machine)? I came across articles which indicated that 'this' pointer is not counted for calculating the size of the object. But I am unable to understand the reason for this.
Also, if any member function is declared virtual, the size of the class is now returned as 4 bytes. This means that the vptr is counted for calculating the size of the object. Why is the vptr considered and 'this' pointer ignored for calculating the size of object?

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

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

发布评论

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

评论(4

幻梦 2024-09-01 13:33:39

this 指针不是该类的成员。它只是在属于该类的方法中使用的构造来引用当前实例。

如果您有一个这样的类:

class IntPair
{
public:
  IntPair(int a, int b) : _a(a), _b(b) { }

  int sum() const { return _a + _b; }

public:
  int _a;
  int _b;
};

该类每个实例只需要两个 int 实例的空间。创建实例并运行 sum() 方法后,将使用指向该实例的指针调用该方法,但该指针始终来自其他位置,不会存储在对象实例。

例如:

IntPair *fib12 = new IntPair(89, 144);

cout << fib12->sum();

请注意成为 this 指针的变量如何存储在对象外部、创建它的作用域中。

事实上,您始终可以将类似于上面的方法转换为:

static int sum2(const IntPair* instance)
{
  return instance->_a + instance->_b;
}

如果上面的方法是在类内部定义的(因此它可以访问私有成员),则没有区别。事实上,这就是在幕后实现方法的方式; this 指针只是所有成员方法的隐藏参数。

该调用将变为:

IntPair* fib12 = new IntPair(89, 144);

cout << IntPair::sum2(fib12);

The this pointer is not a member of the class. It's just a construct that is used in methods belonging to the class to refer to the current instance.

If you have a class like this:

class IntPair
{
public:
  IntPair(int a, int b) : _a(a), _b(b) { }

  int sum() const { return _a + _b; }

public:
  int _a;
  int _b;
};

This class only needs space for two instances of int for each instance. Once you've created an instance and are running the sum() method, that method is called with a pointer to the instance, but that pointer always comes from somewhere else, it isn't stored in the object instance.

For example:

IntPair *fib12 = new IntPair(89, 144);

cout << fib12->sum();

Notice how the variable that becomes the this pointer is stored outside the object, in the scope that created it.

You could, in fact, always transform a method like the one above into:

static int sum2(const IntPair* instance)
{
  return instance->_a + instance->_b;
}

If the above is defined inside the class (so it can access the private members), there's no difference. In fact, this is how methods are implemented behind the scene; the this pointer is just a hidden argument to all member methods.

The call would become:

IntPair* fib12 = new IntPair(89, 144);

cout << IntPair::sum2(fib12);
咽泪装欢 2024-09-01 13:33:39

“this”不作为类中的数据成员存储,它只是指向类实例的“指针”。将其视为传递给该方法的“隐藏参数”。事实上,在 Win32 系统上,它通常在 ecx 寄存器中传递(而不是我最初认为的 eax)。

一旦您拥有 1 个或多个虚拟方法,您的应用程序就需要一种方法来存储指向虚拟方法的指针。这称为 vtable,对于同一类的所有实例来说都是相同的。因为您需要在运行时知道要为哪个“虚拟方法”调用哪个“显式”方法,所以指向 vtable 的指针存储在类实例中。因此,vtable 指针(或 vptr)需要 4 个字节(或 64 位系统上的 8 个字节)。

'this' is not stored as a data member in the class, it's just a 'pointer' to the instance of the class. Consider it as a 'hidden argument' passed to the method. In fact, on Win32 systems it is often passed in the ecx register (not eax as I thought initially).

As soon as you have 1 or more virtual methods, your application needs a way to store the pointers to the virtual methods. This is called the vtable, which is identical for all instances of the same class. Since you need to know at run-time which 'explicit' method to call for which 'virtual method' a pointer to the vtable is stored in the class instance. Therefore the vtable-pointer (or vptr) needs 4 bytes (or 8 bytes on a 64-bit system).

故乡的云 2024-09-01 13:33:39

this 指针不存储在对象内部。没有必要这样做。您已经有一个指针或一个对象来调用函数。至于1的大小,C++标准要求不同的对象具有不同的地址。

The this pointer is not stored inside the object. There's no need to do that. You already have a pointer or an object to invoke the functions on. As for the size of 1, the C++ standard reqires that distict objects have distinct addresses.

卖梦商人 2024-09-01 13:33:39

指针的大小始终是需要在内存中存储的指针类型的大小。

例如,如果 int 的内存地址在 64 位架构上是 32 位,则

int a = 10;
int * b = &a;
大小(b); //32
sizeof(&b); 64

The size of a pointer is always the size of the type of pointer required to be stored in memory.

For example, if memory address of an int is 32-bit on a 64-bit architecture, then

int a = 10;
int * b = &a;
sizeof( b ); //32
sizeof( &b); 64

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