子类转换和指针地址更改

kam*_*iro 6 c++ casting

我已经在c ++中使用了多次继承很长一段时间了,但是今天才意识到这可能意味着指针地址在引用它们作为子类之一时可能会有所不同.

例如,如果我有:

  class ClassA{
     public:
        int x;
        int y;
        ClassA(){
           cout << "ClassA : " << (unsigned int)this << endl;
        }
  };

  class ClassC{
     public:
        int cc;
        int xx;
        ClassC(){
           cout << "ClassC : " << (unsigned int)this << endl;
        }
  };

  class ClassB : public ClassC, public ClassA{
     public:
        int z;
        int v;
        ClassB(){
           cout << "ClassB : " << (unsigned int)this << endl;
        }
  };


  int main(){

     ClassB * b = new ClassB();

  }
Run Code Online (Sandbox Code Playgroud)

在构造函数上打印时,A类和C类具有不同的地址.

然而,当我试图将它们重新投射到彼此时,它只是自动地工作:

ClassA * the_a = (ClassA*)b;
cout << "The A, casted : " << (unsigned int)the_a << endl;

ClassB * the_b = (ClassB*)the_a;
cout << "The B, casted back : " << (unsigned int)the_b << endl;
Run Code Online (Sandbox Code Playgroud)

我想这些信息可以由编译器从代码中派生出来,但可以安全地假设这适用于所有编译器吗?

附加问题:是否可以强制子类位置的顺序?例如,如果我需要首先定位classA(本质上,共享相同的指针位置)和ClassC它的子类,我只需要将它放在子类的声明中吗? 更新好的,看起来无法强制下订单.是否仍然可以找到结构的"根"地址,分配给子类的地址的开始,在超类级别?例如,从ClassA获取classB的地址.

ice*_*ime 7

这是多重继承的完美标准用法,它适用于任何兼容的编译器.但是你应该注意到在第一种情况下显式转换为不必要的,并且static_cast在第二种情况下'C样式转换'可以替换为a .

是否可以强制子类位置的顺序.

否:布局是实现定义的,您的代码不应该依赖于此顺序.