更多c ++多重继承的乐趣

时间:2010-01-28 22:32:56

标签: c++ multiple-inheritance

  

可能重复:
  C++ pointer multi-inheritance fun.

(跟进:C++ pointer multi-inheritance fun

我正在编写一些涉及从基本引用计数指针类继承的代码;并且出现了一些复杂的C ++。我把它减少如下:

假设我有:

class A{int x, y;};
class B{int xx, yy;};
class C: public A, public B {int z;};

C c;
C* pc = &c;
B* pb = &c;
A* pa = &c;

// does pa point to a valid A object?
// does pb point to a valid B object?

// does pa == pb ?

此外,确实:

// pc == (C*) pa ?
// pc == (C*) pb ?

谢谢!

此处,“==”表示相同值的点。

1 个答案:

答案 0 :(得分:3)

  • 没有
  • *

但是你需要知道C ++如何组织内存。类的布局,CClass,如下:

offset
0                              First base class in list of base classes
sizeof first base class        Next base class
sizeof first N-1 base classes  Nth base class
sizeof all base classes        CClass

好吧,如果有一个继承树,它会比那更复杂,但你应该得到基本的想法。假设int是四个字节,那么C类的布局如下:

offset
0             A::x
4             A::y
8             B::xx
12            B::yy
16            C:z

但是C类型的对象都是上面的所有,所以指向C的指针指向偏移量0.但是,C ++允许隐式向下转换,因此指向C的指针可以转换为指向A的指针或者指向B的指针。但是如果你看一下上面的指针,指向B的指针是偏移8而不是0(指向C的指针),指向A的指针是偏移0的指针。所以,铸造一个指向C的指针指向B的指针将指针值加8。这是因为B的方法假设'this'指针指向B的第一个成员(B :: xx),但如果重新解释为指向B的指针(即值相同)则指向C的指针将是指针在B实际存在之前的8个字节的地址,以便所有B的方法都使用,在这个例子中是A的成员。

向上转播(最后两次转换)是不同的鱼。从指针到B到指向C的指针真的很难,因为你不知道指向B的指针是指向B的实例还是指向C的实例加8。这就是RTTI和动态强制转换的用武之地。启用RTTI(运行时类型信息)后,指向B的指针包含描述B实际上是什么的附加信息 - 一个简单的B或B作为C的一部分。这确实有额外的成本,执行时间和内存使用。

最后,这确实突出了C风格演员的模糊性。你真的应该使用C ++样式转换(static_cast<>等),因为这澄清了转换的方式。

* 这也可能是肯定的,我想这取决于编译器以及RTTI是打开还是关闭。您需要深入了解标准和编译器实现的细节。