(C++)upcast的时候一定要用 dynamic_cast 吗?

如果是多继承,并且 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类的地址。

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值