C++ 具有单个继承的类的指针强制转换偏移量

C++ 具有单个继承的类的指针强制转换偏移量,c++,pointers,casting,polymorphism,language-lawyer,C++,Pointers,Casting,Polymorphism,Language Lawyer,在学习“有效的C++”时,我首先感到惊讶的是,当我了解到这样一个事实:如果一个类具有多重继承,那么在完成指针转换时,它的指针可能会偏移。虽然这不是一个容易掌握的概念,但我想我还是设法做到了 然而,作者声称这种偏移甚至可能发生在单个继承类的指针转换中。我不知道会是什么情况,并希望知道背后的理由 class B { int a = 0; }; class D : public B { virtual ~D() = default; }; D有一个虚拟成员。B没有。C++中动态调度的一种常

在学习“有效的C++”时,我首先感到惊讶的是,当我了解到这样一个事实:如果一个类具有多重继承,那么在完成指针转换时,它的指针可能会偏移。虽然这不是一个容易掌握的概念,但我想我还是设法做到了

然而,作者声称这种偏移甚至可能发生在单个继承类的指针转换中。我不知道会是什么情况,并希望知道背后的理由

class B {
  int a = 0;
};

class D : public B {
  virtual ~D() = default;
};
D有一个虚拟成员。B没有。C++中动态调度的一种常见实现是在对象的开始时将隐藏指针保持到函数地址表。
这意味着B子对象的第一个字节不在完整D对象的开头。指针转换需要根据vptr大小调整地址。

当派生类将多态性引入类层次结构时,可能会发生这种情况。考虑下面的类:

struct Foo
{
    int a;
    int b;
};
此类不是多态的,因此实现不需要包含指向虚拟调度表的指针(实现虚拟调度的常用方法)。它将被放置在内存中,如下所示:

  Foo
  +---+
a |   |
  +---+
b |   |
  +---+
               Bar
               +---------+
vtable pointer |         |
               +---------+
 Foo subobject |   +---+ |
               | a |   | |
               |   +---+ |
               | b |   | |
               |   +---+ |
               +---------+

现在考虑继承自<代码> FoO >的类:

struct Bar : Foo
{
    virtual ~Bar() = default;
};
这个类是多态的,所以这个类的对象需要包含一个指向vtable的指针,这样进一步的派生类就可以覆盖
Bar
的虚拟成员函数。这意味着
Bar
对象在内存中的布局如下:

  Foo
  +---+
a |   |
  +---+
b |   |
  +---+
               Bar
               +---------+
vtable pointer |         |
               +---------+
 Foo subobject |   +---+ |
               | a |   | |
               |   +---+ |
               | b |   | |
               |   +---+ |
               +---------+
由于对象的
Foo
子对象不在对象的开头,因此从指向
Bar
对象的指针初始化的任何
Foo*
都需要根据指针的大小进行调整,以便它实际指向
Bar
对象的
Foo
子对象


当强制转换完成时,类指针可能会偏移,并且类涉及多重继承
请发布一个代码示例。它是什么意思
指针可能有偏移量
<代码>铸造完成时
-什么铸造?铸造什么?到哪种类型,从哪种类型<代码>涉及多继承(< /代码>)-涉及如何?@ KAMILCK我的道歉是我的问题是关于C++编程中的一些抽象概念。我曾考虑为其添加一些示例,但已经发布了带有具体示例的好答案。