static_cast, dynamic_cast, const_cast and reinterpret_cast之间的区别
自己把gg上内容翻译了一下,有好多知识点都是自己不懂的,希望有大佬后面指点一下。
一、static_cast
①首先要考虑用到的投射转换。 ②作用和隐式转换相似(如将int转换为float,函数指针转换为void*) 也可以作为显示转换。但是在很多地方,显式转换是不必要,但是须知道T(something) 和(T)something定义相同。 但是应该避免使用T(something),而更多地使用(T)something。T(something, something_else)是安全的,因为该调用中保证调用没有构造函数。 ⑤static_cast还可以用在继承链中。 *** 向上转换(转换成基类)不必使用static_cast。但是当派生类没有由基类虚继承时,向下转换(转换为子类)必须使用static_cast。 *** static_cast不会进行类型检查,所以将某个对象向下转换为非这个对象实际类型时,就会产生未定义问题。
二、const_cast
①为变量删除或添加 const 属性。 没有其他 C++转换能够删除const(reinterpret_cast 也不行)。 ②若原始变量是 const 声明的,修改其值会抛出未定义错误。; ③某些未用const声明的函数、变量,你可以使用const_cast从它的引用上去除const属性。 比如,基于const成员函数的重载可以使用const_cast。 ④在一个对象增加const属性时是有用的,可以调用重载的成员函数。 ⑤const_cast 与 volatile 有类似的作用,尽管这种情况不太常见。
三、dynamic_cast
①广泛用于多态中, ②可以将多态类型的指针或引用转换为任何其他类类型(一个多态类型至少有一个虚函数,用于被声明和被继承)。 ③不仅可以用于向下转换 - 还可以向侧面转换和向上转换。 ④dynamic_cast 将寻找所需的对象并在可能的情况下返回它。 如果不能,在使用指针情况下将返回空指针 nullptr,在引用的情况下抛出 std::bad_cast。 ⑤dynamic_cast 有一些限制。 ** 如果继承层次结构中有多个相同类型的对象(所谓的“可怕的菱形”)并且没有使用虚拟继承,则dynamic_cast不起作用。 ** 只能用于公共继承中。如果是protected或者private继承,将造成转换失败。
四、reinterpret_cast
①reinterpret_cast是一种最危险的转换,应该尽可能少地使用。 它将一种类型直接转换为另一种类型——例如将一个指针的值转化为转换为另一个(指针的值),或将指针存储在 int 中等等。 reinterpret_cast通常可以将结果转换回原始类型(但如果中间类型小于原始类型,则不会)。 存在很多reinterpret_cast 无法进行的转换。 ②reinterpret_cast主要用于特殊的转换和位操作: 例如将原始数据流转换为实际数据; 或将数据存储在指向对齐数据的指针的低位中。
五、C-style cast and function-style cast
①他们的形式是(type)object 或者type(object),两者作用等价。 ②在某些情况下,他们可以替换其他的转换。但当替换reinterpret_cast是比较危险的,reinterpret_cast在动态转换中更加适用; 除非当static_cast转换成功,而reinterpret_cast转换失败时, ③在执行 static_cast 时,C-style cast的强制转换也会忽略访问控制,这意味着他们有能力执行其他转换无法执行的操作。 这可能是一个冗余,只是为了避免C-style cast转换。
以下为google上大佬的原答案,请各位直接参阅。 原文链接stackoverflow 传送门
以上仅作为自己学习使用,如有侵权,请及时告知,将进行删稿,
|