C++派生多态类 - 它是否包含 Base 的整个实例,包括 vptr?

发布于 2024-12-06 02:10:26 字数 355 浏览 1 评论 0原文

假设我们有

Class A
{
   public:
   int _i;
   virtual int getI();
};
class B : public A
{  
   public:
   int _j;
   virtual int getI();
};

那么假设内存中类的大小是其成员的总和(即忽略填充或实际可能发生的任何情况),B 实例的大小是多少?是 sizeof(A) + sizeof(int) + sizeof(vptr) 吗?或者 B 实例在其个人 A 实例中是否不包含 A vptr,因此 sizeof(b) 将是 sizeof(int) + sizeof(int) + sizeof(vptr)?

Say we have

Class A
{
   public:
   int _i;
   virtual int getI();
};
class B : public A
{  
   public:
   int _j;
   virtual int getI();
};

So assuming that the size of a class in memory is the sum of its members (i.e. ignoring padding or whatever might actually happen), what is the size of a B instance? Is it sizeof(A) + sizeof(int) + sizeof(vptr)? Or does a B instance not hold an A vptr in it's personal A instance, so that sizeof(b) would be sizeof(int) + sizeof(int) + sizeof(vptr)?

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

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

发布评论

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

评论(4

神经大条 2024-12-13 02:10:26

它是实现使代码正常工作所需的任何内容。所有的你
可以说它至少是2 * sizeof(int),因为对象
B 类型包含两个 int(可能还有其他东西)。在一个典型的
实现时,AB将共享一个vptr,总大小为
只比两个整数多一个指针(模填充
对齐,但在大多数实现中,我认为不会有
任何)。但这只是一个典型的实现;你不能指望它。

It's whatever the implementation needs to make the code work. All you
can say is that it is at least 2 * sizeof(int), because objects of
type B contain two ints (and possibly other things). In a typical
implementation, A and B will share a vptr, and the total size will
be just one pointer more than the two ints (modulo padding for
alignment, but on most implementations, I don't think that there will be
any). But that's just a typical implementation; you can't count on it.

浅语花开 2024-12-13 02:10:26

任何有关 vtable 的讨论都将特定于某个实现,因为即使 vtable 的存在也不是由 C++ 标准指定的 - 它是一个实现细节。

一般来说,一个对象只有一个指向 vtable 的指针,并且该 vtable 将在该类型的所有对象之间共享。派生类将在表中包含基类的每个虚函数以及它未继承的每个新虚函数的指针,但同样,这是一个静态表,并且它不是目的。

要实际回答这个问题,最可能的结果是 sizeof(B) == sizeof(A::_i) + sizeof(B::_j) + sizeof(vptr)。

Any talk of a vtable is going to be specific to a certain implementation, since even the existance of a vtable isn't specified by the C++ standard - it's an implementation detail.

Generally an object will only have one pointer to a vtable, and that vtable will be shared among all objects of that type. The derived class will contain pointers in the table for each virtual function of the base classes plus each new virtual function that it didn't inherit, but again this is a static table and it is not part of the object.

To actually answer the question, the most likely outcome is sizeof(B) == sizeof(A::_i) + sizeof(B::_j) + sizeof(vptr).

瞄了个咪的 2024-12-13 02:10:26

你为什么想知道?如果您打算在程序中使用它,我会尝试寻找一种比计算它更便携的方法,并添加一个返回大小的虚拟函数,或者使用运行时类型信息来获取正确的类型,然后返回尺寸。

(如果您投票或添加评论,我将开始装饰答案)

Why would you want to know? If you are going to use that in your program, I'd try to look for a more portable way than calculate it and either add a virtual function that returns the size, or perhaps use the runtime type infomration to get the correct type and then return the size.

(if you vote up or add comments I'll start decorating the answer)

深海不蓝 2024-12-13 02:10:26

除了 James Kanze 所说的之外,也许值得一提的是(在典型的实现中)B 的虚拟表将在其开头包含 A 的虚拟表。

例如:

class A {
    virtual void x();
    virtual void y();
};

class B : A {
    virtual void y();
    virtual void z();
};

A 的虚拟表:

  • A:x()
  • A:y()

B 的虚拟表:

  • A:x()
  • B:y()
  • B:z()

这就是为什么 B 的实例可以只需一个虚拟表指针即可。

顺便说一句,多重继承会使事情变得相当复杂,并为每个对象引入多个虚拟表指针。

始终记住,所有这些都是实现细节,您永远不应该编写依赖于它的代码。

In addition to what James Kanze said, it is perhaps worth mentioning that (on a typical implementation) the B's virtual table will contain A's virtual table at its beginning.

For example:

class A {
    virtual void x();
    virtual void y();
};

class B : A {
    virtual void y();
    virtual void z();
};

A's virtual table:

  • A:x()
  • A:y()

B's virtual table:

  • A:x()
  • B:y()
  • B:z()

That's why an instance of B can get away with just one virtual table pointer.

BTW, multiple inheritance can complicate things quite a bit and introduce multiple virtual table pointers per object.

Always keep in mind that all this is an implementation detail and you should never write code that depends on it.

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