Chu*_*dad 7 c++ virtual base-class pointer-to-member
$ 4.11/2州 -
类型为" cv
B类型成员的指针"的rvalue ,其中是类类型,可以转换为类型为"指向cv类型 成员的指针"的rvalue ,其中是派生类(第10节).如果不可访问(第11条),模糊(10.2)或虚拟(10.1)基类 ,则需要进行此转换的程序是不正确的.TBDTDBBD
我的问题是为什么我们有限制B不是虚拟基类D?
考虑涉及非虚基类的情况:
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子对象,因为它继承自B和C都有一个A子对象.
成员变量的指针通常实现为从对象开头的整数偏移量.在这种情况下,整数偏移用于int a在A对象是零.因此,"指向int a类型的指针A"可以只是零的整数偏移量.
一个"指针转换int a型A"到"指针int a类型的B,"你只需要一个整数偏移到A位于子对象B(第一A子对象).
一个"指针转换int a型A"到"指针int a类型的C,"你只需要一个整数偏移到A位于子对象C(第二A子对象).
由于编译器知道在哪里B和C相对A,编译器有足够的信息如何向下转换A为B或C.
现在考虑涉及虚拟基类的情况:
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)
虚拟基类通常通过具有B和C(实际上源自A)包含指向单个子A对象的指针来实现.指向A子对象的指针是必需的,因为A相对于B且C不是常量的位置.
如果我们只有"指向int a类型的指针A",我们将无法将其转换为"指向int a类型的指针B",因为B和C子对象的位置可能相对于A.A没有后向指针B也没有C,所以我们根本没有足够的信息让downcast工作.
非常有趣的问题。今天学到了新东西。这是我可以找到与该主题相关的内容: Casting member function pointers from obliged class to virtual base class does not work
| 归档时间: |
|
| 查看次数: |
452 次 |
| 最近记录: |