C++ 中的强制类型转换

  显示转换也成为强制类型转换(cast),包括以下列名字命名的强制类型转换操作符:static_cast、dynamic_cast、const_cast、reinterpret_cast。

1. const_cast  const_cast<TYPE> (object); 

   The const_cast keyword can be used to remove the const or volatile property from an object. The target data type must be the same as the source type, except (of course) that the target type doesn't have to have the same const qualifier. The type TYPE must be a pointer or reference type.

 2. static_cast  static_cast<TYPE> (object);

  The static_cast keyword can be used for any normal conversion between types. This includes any casts between numeric types, casts of pointers and references up the hierarchy, conversions with unary constructor, conversions with conversion operator. For conversions between numeric types no runtime checks if data fits the new type is performed. Conversion with unary constructor would be performed even if it is declared as explicitIt can also cast pointers or references down and across the hierarchy as long as such conversion is available and unambiguous. No runtime checks are performed

3. dynamic_cast  dynamic_cast<TYPE&> (object);  dynamic_cast<TYPE*> (object)

  The dynamic_cast keyword casts a datum from one pointer or reference type to another, performing a runtime check to ensure the validity of the cast. 

  If you attempt to cast to a pointer type, and that type is not an actual type of the argument object, then the result of the cast will be NULL.

  If you attempt to cast to a reference type, and that type is not an actual type of the argument object, then the cast will throw a std::bad_cast exception.

   用于将基类类型对象的引用或者指针转换为同一继承层次中其他类型的引用或者指针。使用指针时,指针必须是有效的,为0或者指向一个对象。与其他强制类型转换不同,它涉及运行时类型检查。如果绑定到引用或者指针的对象不是目标类型的对象,则dynamic_cast转换失败。如果转换到指针类型的dynamic_cast失败,则dynamic_cast的结果是0值;如果转换到引用类型的dynamic_cast失败,则抛出一个bad_cast类型的异常。

  一般而言,引用或者指针所绑定的对象的类型在编译时是未知的,基类的指针可以赋值为指向派生类对象,同样,基类的引用也可以用派生类对象初始化,因此dynamic_cast操作符执行的验证必须在运行时进行。

dynamic_cast
if (Derived *derivedPtr = dynamic_cast<Derived*>(basePtr))
{
        
//     use the Derived object to which derivedPtr points
else
        
// BasePtr points at a Base object
        
// use the Base object to which basePtr points
    }

void f(const Base &b)
{
    
try {
            
const Derived &= dynamic_cast<const Derived&>(b);
            
// use the Derived object to which b referred
        } catch (bad_cast) {
            
// handle the fact that the cast failed
        }
}

4. reinterpret_cast  reinterpret_cast<TYPE> (object);

  The reinterpret_cast operator changes one data type into another. It should be used to cast between incompatible pointer types.

Different operators for different uses

The four casting operators in C++ can be used in different cases, where each is most appropriate:

static_cast is the most useful cast. It can be used to perform any implicit cast. When an implicit conversion loses some information, some compilers will produce warnings, and static_cast will eliminate these warnings. Making implicit conversion through static_cast is also useful to resolve ambiguity or to clarify the conversion presence. It also can be used to call a unary constructor, declared as explicit. It also can be used to cast up and down a class hierarchy, like dynamic_cast, except that no runtime checking is performed.

const_cast is used to apply or remove const or volatile qualifier from a variable.

dynamic_cast is used on polymorphic pointers or references to move up or down a class hierarchy. Note that dynamic_cast performs runtime-checks: if the object's type is not the one expected, it will return NULL during a pointer-cast and throw a std::bad_cast exception during a reference-cast.

reinterpret_cast is used to perform conversions between unrelated types, like conversion between unrelated pointers and references or conversion between an integer and a pointer.

Old-style cast may correspond to static_cast, reinterpret_cast or const_cast, or even a combination of them. This means that none of these casting operators is as powerful as old-style cast.

小记:

  1、static_cast不进行错误检查,可以进行的转换有:数字类型、继承层次中的指针或引用、声明为explicit的单形参构造函数。只要用来进行替换编译器进行的    隐式转换。

  2、dynamic_cast进行错误检查,可以进行的转换:继承层次中的指针或者引用。 

  3、const_cast用来添加或者去掉一个变量的const或者volatile属性,这个变量必须是指针或引用类型。 

  4、旧时转型(C风格转型)有两种形式:(T) expression 或 T (expression)。两种形式并无差别,纯粹只是小伙考的位置不同。如:

class Widget {
public:
  
explicit Widget(int size);
}; 
void doSomeWork (const Widget& w);
doSomeWork( Widget(
15) );            //旧风格
doSomeWork( static_cast<Widget>(15) );   //新风格 

   5、const_cast 通常被用来将对象的常量性移除。它也是唯一有此能力的C++ style 转型操作符。static_cast 用来强迫隐式转换,例如将 non_const 对象转换为cosnt 对象(就像条款3所为),但它无法将const转换为非const。

  6、static_cast 可以将一个derived class对象转换为base class对象。但static_cast返回一个derived class对象的base class部分的一个副本:

class Window {
pubilc:
    
virtual void onResize(){...}
    ...
};
class SpecialWindow: public Window {
public:
    
virtual void onResize() {
        static_cast
<Window>(*this).onResize(); //Error, 应该为Window::onResize(); 注意优先级相同、左结合
        
//这里进行SpecialWindow的专属行为
    }
    ...
}; 

  错误的行,实际上对*this并无任何改变。改正后可以正确对*this调用函数,产生改变。(Effective C++ 条款27)

  7、如果可能,尽量避免转型,特别是在注重效率的代码中避免dynamic_cast。 

参考:http://www.cppreference.com/wiki/keywords/casting_comparison

原文地址:https://www.cnblogs.com/younes/p/1658965.html