7

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

4

4 回答 4

6

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);
于 2010-03-18T07:37:47.660 回答
4

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

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

于 2010-03-18T07:38:14.573 回答
2

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

于 2010-03-18T07:38:15.960 回答
-1

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

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

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

于 2012-04-30T06:44:35.793 回答