在线时间:8:00-16:00
迪恩网络APP
随时随地掌握行业动态
扫描二维码
关注迪恩网络微信公众号
郑重声明:本文是笔者根据个人理解所写,错误难免,欢迎拍砖! 可以任意转载、修改,转载时是否标明出处,随君而定! static_cast用于“良性”和“适度良性”转换,包括不用强制转换(如自动类型转换)。static_cast全部用于明确定义的转换,包括编译器允许我们所做的不用强制转换的“安全”转换和不太安全但清楚定义的转换。 用法:static_cast < type-id > ( expression) A、典型的非强制变换 B、窄化(有信息丢失)变换 C、使用void*的强制变换 D、隐式类型变换 E、类层次的静态定位 a. 向上转换是安全的,即将子类的指针或引用转换为基类 1 int i = 0x7fff; // max pos value = 32767 2 long l = 0; 3 float f = 1.0f; 4 5 // A: typeical castless conversions: 6 l = static_cast<long>(i); 7 8 // B: narrowing conversions: 9 i = static_cast<int>(f); 10 11 // C: forcing a conversion from void* : 12 void* pvoid = &i; 13 float* pf = static_cast<float*>(pvoid); 14 15 // D: Implicit type conversions, normally performed by the compiler 16 double d = 0.0; 17 int x = d; // Automatic type conversion 18 x = static_cast<int>(d); // More explicit 注意:static_cast不能转换掉expression的const、volitale、或者__unaligned属性。 dynamic_cast用法:dynamic_cast < type-id > ( expression ) 当使用dynamic_cast来试着向下类型转换一个特定的类型,仅当类型转换是争取的并且是成功的时,返回值是一个指向所需类型的指针,否则它将返回0来表示转换失败。 dynamic_cast主要用于类层次间的上行转换和下行转换,还可以用于类之间的交叉转换。 在进行下行转换时,dynamic_cast具有类型检查的功能,比static_cast更安全。 1 #include <iostream> 2 using namespace std; 3 4 class CPet { public : virtual ~CPet() {} }; 5 class CDog : public CPet {}; 6 class CCat : public CPet {}; 7 8 int main() 9 { 10 CPet* pPet = new CCat; // Upcast, safe 11 // Try to cast it to CCat* : 12 CCat* pCat = dynamic_cast<CCat*>(pPet); // cast success 13 // Try to cast it to CDog* : 14 CDog* pDog = dynamic_cast<CDog*>(pPet); // cast fail 15 16 cout << "pDog = " << (long)pDog << endl; 17 cout << "pCat = " << (long)pCat << endl; 18 } 在上面的代码段中,将pPet向下转换为CCat*类型成功了(因为CPet* pPet = new CCat;),转换为CDog*类型失败了,说明dynamic_cast会进行类型检测。 当使用dynamic_cast时,必须对一个真正多态的层次进行操作(即它含有虚函数),这是因为dynamic_cast使用了存储在VTABLE中的信息来判断实际的类型。 注意:无论何时进行向下类型转换,我们都应该进行类型检查以确保转换是成功的(即返回值非0)。但我们不用确保指针要完全一样,因为通常在向上和向下类型转换时指针会进行调整(特别是多重继承的情况下)。 dynamic _cast运行时需要一点额外的开销,不多,但是执行大量的dynamic_cast时就说明我们的设计有问题了,也会导致性能损失。在进行向下转换时,如果我们已经明确知道是什么类型,就可以使用static_cast,以避免调用dynamic_cast产生的额外开销。比如上面的将pPet向下转换为CCat*类型,可以这样写: CCat* pCat = static_cast<CCat*>(pPet); reinterpret_cast这是最不安全的一种转换机制,最有可能出问题。reinterpret_cast把对象假象为模式(为了某种隐秘的目的),仿佛它是一个完全不同的类型对象。这是低级的位模式,C因此而名称不佳。在使用reinterpret_cast做任何事之前,实际上总是需要reinterpret_cast回到原来的类型(或者把变量看做是它原来的类型)。说白了,就是将原来的类型隐藏起来,用的时候再转换回去,否则编译失败。 用法:reinterpret_cast< type-id > (expression) const_castconst_cast用来修改类型的const或volatile属性,即可以将const转换为非const以及volatile转换为非volatile,这是const_cast唯一允许的转换。除了const 或volatile修饰之外, type_id和exdivssion的类型是一样的。 Voiatile和const类试。举如下一例: 1 class B 2 { 3 public: 4 int m_iNum; 5 } 6 void foo() 7 { 8 const B b1; 9 b1.m_iNum = 100; //comile error 10 B b2 = const_cast<B>((b1); 11 b2. m_iNum = 200; //fine 12 } 上面的代码编译时会报错,因为b1是一个常量对象,不能对它进行改变; 使用const_cast把它转换成一个常量对象,就可以对它的数据成员任意改变。注意:b1和b2是两个不同的对象。 简单总结一下: dynamic_cast: 通常在基类和派生类之间转换时使用;
参考资料: http://blog.csdn.net/Lambol_8309/article/details/4534338 http://blog.sina.com.cn/s/blog_4a84e45b0100f57m.html |
2023-10-27
2022-08-15
2022-08-17
2022-09-23
2022-08-13
请发表评论