| 如果是多继承,并且 upcast到不同的接口的时候,需要用dynamic_cast 比如,下面的代码,第37行一定要用 dynamic_cast,因为它是从一个 基类接口转到另外一个基类借口。      1	class A
     2	{
     3	public:
     4	virtual bool IsA(void) = 0;
     5	protected:
     6	int t_a;
     7	};
     8	
     9	class B
    10	{
    11	public:
    12	virtual bool IsB( void ) = 0;
    13	protected:
    14	int t_b;
    15	};
    16	
    17	class C: public A, public B
    18	{
    19	public:
    20	
    21	C(){}
    22	~C(){}
    23	bool IsA(void) { return true;}
    24	bool IsB(void) { return true;}
    25	
    26	virtual bool isC(void){return true;}
    27	private:
    28	int m_c;
    29	};
    30	
    31	int main(void)
    32	{
    33		A *pA = new C;
    34	
    35		C * pC = (C*)pA;
    36		B *pB = (B*)pA;
    37		B *pB2 = dynamic_cast<B*>(pA);
    38	
    39		return 0;
    40	}
 使用GDB打印变量的值: (gdb) p pA$2 = (A *) 0x804fa10
 (gdb) p pB
 $3 = (B *) 0x804fa10
 (gdb) p pB2
 $4 = (B *) 0x804fa18
 可以看到,pB 和 pB2的值不一样。 使用命令 clang -cc1 -fdump-record-layouts 打印出类的内存分布: *** Dumping AST Record Layout
         0 | class A
         0 |   (A vtable pointer)
         4 |   int t_a
           | [sizeof=8, dsize=8, align=4,
           |  nvsize=8, nvalign=4]
*** Dumping AST Record Layout
         0 | class B
         0 |   (B vtable pointer)
         4 |   int t_b
           | [sizeof=8, dsize=8, align=4,
           |  nvsize=8, nvalign=4]
*** Dumping AST Record Layout
         0 | class C
         0 |   class A (primary base)
         0 |     (A vtable pointer)
         4 |     int t_a
         8 |   class B (base)
         8 |     (B vtable pointer)
        12 |     int t_b
        16 |   int m_c
           | [sizeof=20, dsize=20, align=4,
           |  nvsize=20, nvalign=4]
 可以看到,类B在 C 对象上的偏移为 8, 可以看到,dynamic_cast后的值就是对应的B类的地址。 |