指向成员问题的指针

Chu*_*dad 7 c++ virtual base-class pointer-to-member

$ 4.11/2州 -

类型为" cvB类型成员的指针"的rvalue ,其中是类类型,可以转换为类型为"指向cv类型 成员的指针"的rvalue ,其中是派生类(第10节).如果不可访问(第11条),模糊(10.2)或虚拟(10.1)基类 ,则需要进行此转换的程序是不正确的. TBD TDBBD

我的问题是为什么我们有限制B不是虚拟基类D

In *_*ico 5

考虑涉及非虚基类的情况:

class A { int a; }
class B : public A { int b; }
class C : public A { int c; }
class D : public B, public C { int d; }
Run Code Online (Sandbox Code Playgroud)

这是一个可能的内存布局:

+-------------+
| A: int a;   |
+-------------+
| B: int b;   |
+-------------+
| A: int a;   |
+-------------+
| C: int c;   |
+-------------+
| D: int d;   |
+-------------+
Run Code Online (Sandbox Code Playgroud)

D最终有两个A子对象,因为它继承自BC都有一个A子对象.

成员变量的指针通常实现为从对象开头的整数偏移量.在这种情况下,整数偏移用于int aA对象是零.因此,"指向int a类型的指针A"可以只是零的整数偏移量.

一个"指针转换int aA"到"指针int a类型的B,"你只需要一个整数偏移到A位于子对象B(第一A子对象).

一个"指针转换int aA"到"指针int a类型的C,"你只需要一个整数偏移到A位于子对象C(第二A子对象).

由于编译器知道在哪里BC相对A,编译器有足够的信息如何向下转换ABC.

现在考虑涉及虚拟基类的情况:

struct A { int a; }
struct B : virtual public A { int b; }
struct C : virtual public A { int c; }
struct D : public B, public C { int d; }
Run Code Online (Sandbox Code Playgroud)

可能的内存布局:

+-------------+
| B: ptr to A | ---+
|    int b;   |    |
+-------------+    |
| C: ptr to A | ---+
|    int c;   |    |
+-------------+    |
| D: int d;   |    |
+-------------+    |
| A: int a;   | <--+
+-------------+
Run Code Online (Sandbox Code Playgroud)

虚拟基类通常通过具有BC(实际上源自A)包含指向单个子A对象的指针来实现.指向A子对象的指针是必需的,因为A相对于BC不是常量的位置.

如果我们只有"指向int a类型的指针A",我们将无法将其转换为"指向int a类型的指针B",因为BC子对象的位置可能相对于A.A没有后向指针B也没有C,所以我们根本没有足够的信息让downcast工作.


cel*_*vek 0

非常有趣的问题。今天学到了新东西。这是我可以找到与该主题相关的内容: Casting member function pointers from obliged class to virtual base class does not work