WEB开发网
开发学院软件开发VC static_cast<>揭密 阅读

static_cast<>揭密

 2007-03-15 21:54:22 来源:WEB开发网   
核心提示: CDerived的内存布局(Memory Layout)如图所示,CDerived的内存布局包括两个对象,static_cast<>揭密(3),CBaseX 和 CBaseY,编译器也知道这一点,2. dynamic_cast<>需要类成为多态,即包括“

CDerived的内存布局(Memory Layout)

如图所示,CDerived的内存布局包括两个对象,CBaseX 和 CBaseY,编译器也知道这一点。因此,当你将CDerived* 转换到 CBaseY*时,它给指针添加4个字节,同时当你将CBaseY*转换到CDerived*时,它给指针减去4。然而,甚至它即便不是一个CDerived你也可以这样做。

当然,这个问题只在如果你做了多继承时发生。在你将CDerived转换 到 CBaseX时static_cast<> 和 reinterpret_cast<>是没有区别的。

情况3:void*之间的向前和向后转换

因为任何指针可以被转换到void*,而void*可以被向后转换到任何指针(对于static_cast<> 和 reinterpret_cast<>转换都可以这样做),如果没有小心处理的话错误可能发生。

  CDerived* pD = new CDerived();
    printf("CDerived* pD = %x
", (int)pD);
   
CBaseY* pY = pD; // 成功编译, pY = pD + 4
    printf("CBaseY* pY = %x
", (int)pY);
   
void* pV1 = pY; //成功编译, pV1 = pY
    printf("void* pV1 = %x
", (int)pV1);
   
// pD2 = pY, 但是我们预期 pD2 = pY - 4
    CDerived* pD2 = static_cast<CDerived*>(pV1);
    printf("CDerived* pD2 = %x
", (int)pD2);
    // 系统崩溃
    // pD2->bar();
    ---------------------- 输出 ---------------------------
    CDerived* pD = 392fb8
    CBaseY* pY = 392fbc
    void* pV1 = 392fbc
    CDerived* pD2 = 392fbc

一旦我们已经转换指针为void*,我们就不能轻易将其转换回原类。在上面的例子中,从一个void* 返回CDerived*的唯一方法是将其转换为CBaseY*然后再转换为CDerived*。

但是如果我们不能确定它是CBaseY* 还是 CDerived*,这时我们不得不用dynamic_cast<> 或typeid[2]。

注释:

1. dynamic_cast<>,从另一方面来说,可以防止一个泛型CBaseY* 被转换到CDerived*。

2. dynamic_cast<>需要类成为多态,即包括“虚”函数,并因此而不能成为void*。

参考:

1. [MSDN] C++ Language Reference -- Casting

2. Nishant Sivakumar, Casting Basics - Use C++ casts in your VC++.NET programs

3. Juan Soulie, C++ Language Tutorial: Type Casting

上一页  1 2 3 

Tags:static cast lt

编辑录入:爽爽 [复制链接] [打 印]
赞助商链接