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操作符执行的验证必须在运行时进行。

ExpandedBlockStart.gif 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/archive/2010/01/29/1658965.html

### C++ 强制类型转换方法及其使用指南 #### 新式转型概述 在C++中,强制类型转换被称为新式转型,区别于C语言中的旧式转型。新式转型提供了四种不同的关键字来执行特定类型的转换操作:`static_cast`、`dynamic_cast`、`const_cast` 和 `reinterpret_cast`[^1]。 #### Static Cast (静态转换) `static_cast` 是一种编译期检查的类型转换机制,适用于基本数据类型间的相互转换以及具有继承关系的对象之间安全的方向上的转换。例如: ```cpp double dValue = 3.14; int iValue = static_cast<int>(dValue); ``` 对于指针或引用来说,当基类和派生类存在单根继承体系时可以实现向下转型(即从基类到派生类),但是这种情况下应该优先考虑使用更安全的方式——`dynamic_cast`。 #### Dynamic Cast (动态转换) `dynamic_cast` 主要用于处理多态对象之间的转换,在运行期间能够判断两个类型间是否存在合法的关系并返回相应结果。如果尝试非法的操作,则会抛出异常或者返回null指针取决于具体场景。这使得它成为最安全但也可能是性能开销最大的选项之一: ```cpp Base* basePtr = new Derived(); Derived* derivedPtr = dynamic_cast<Derived*>(basePtr); if(derivedPtr != nullptr){ // 成功转换... } else{ // 转换失败... } ``` 此功能特别适合用来验证是否可以从某个已知接口获取更加具体的实例化版本[^3]。 #### Const Cast (常量属性修改) `const_cast` 的作用在于移除变量声明时所附加的 const 或 volatile 属性。虽然有时确实有必要这样做,但在大多数时候应当尽量避免改变原本设计意图下的不可变性约束,因为这可能会引发未定义行为的风险。 ```cpp void someFunction(const int& value){ int* nonConstValue = const_cast<int*>(&value); (*nonConstValue)++; } // 注意上述做法并不推荐除非有充分理由证明其安全性。 ``` #### Reinterpret Cast (重新解释位模式) 最后是 `reinterpret_cast`, 它允许程序员直接操纵底层二进制表示形式来进行几乎任何种类的数据视图变换。然而由于缺乏语义层面的理解和支持,误用该特性极易造成难以调试的问题甚至危及整个系统的稳定性。因此仅限于那些真正需要低级控制的应用场合下谨慎采用,并且通常只会在非常特殊的情况下才会涉及到此类操作[^2][^4]: ```cpp uintptr_t rawAddress = reinterpret_cast<uintptr_t>(&someObject); void* genericPointer = reinterpret_cast<void*>(rawAddress); ``` 综上所述,每种类型转换都有各自适用范围内的最佳实践指导原则,合理选择合适的工具可以帮助开发者写出既高效又可靠的代码。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值