当前位置:  编程语言>c/c++

标准c++四种强制类型转换方式介绍

 
    发布时间:2013-9-9  


    本文导语:  C风格的强制类型转换(Type Cast)很简单,不管什么类型的转换统统是:  TYPE b = (TYPE)a C++风格的类型转换主要提供了4种类型转换操作符来应对不同场合的应用:const_cast,从字面上理解就是去const属性。static_cast,从字...

  C风格的强制类型转换(Type Cast)很简单,不管什么类型的转换统统是:  

TYPE b = (TYPE)a

 c++风格的类型转换主要提供了4种类型转换操作符来应对不同场合的应用

const_cast,从字面上理解就是去const属性

static_cast,从字面上理解理解就是静态类型转换。如int转换成char

dynamic_cast,从字面上理解理解就是动态类型转换。如子类和父类之间的多态类型转换。

reinterpreter_cast,从字面上理解就是仅仅重新解释类型,但没有进行二进制转换

1)static_cast<T*>(a)

  将地址a转换成类型T,T和a必须是指针引用算术类型或枚举类型

  表达式static_cast<T*>(a), a的值转换为模板中指定的类型T。在运行时转换过程中,不进行类型检查来确保转换的安全性

举例如下:

(1)

class B { ... };
class D : public B { ... };
void f(B* pb, D* pd)
{
   D* pd2 = static_cast<D*>(pb);        // 不安全, pb可能只是B的指针
   B* pb2 = static_cast<B*>(pd);        // 安全的
   ...
}

(2)

class B { ... };
class D : public B { ... };
void f(B* pb, D* pd)
{
   D* pd2 = static_cast<D*>(pb);        // 不安全, pb可能只是B的指针
   B* pb2 = static_cast<B*>(pd);        // 安全的
   ...
}

(3)

class B { ... };
class D : public B { ... };
void f(B* pb, D* pd)
{
   D* pd2 = static_cast<D*>(pb);        // 不安全, pb可能只是B的指针
   B* pb2 = static_cast<B*>(pd);        // 安全的
   ...
}

(4)

int n = 6;
double d = static_castdouble>(n); // 基本类型转换
int *pn = &n;
double *d = static_castdouble *>(&n) //无关类型指针转换,编译错误
void *p = static_castvoid *>(pn); //任意类型转换成void类型

2)dynamic_cast<T*>(a)

  完成层次结构中的提升。T必须是一个指针、引用或无类型的指针。a必须是决定一个指针或引用的表达式。表达式dynamic_cast<T*>(a) 将a值转换为类型为T的对象指针。如果类型T不是a的某个基类型,该操作将返回一个空指针

例子:

(1)

class A { ... };
class B { ... };
void f()
{
  A* pa = new A;
  B* pb = new B;
  void* pv = dynamic_cast<A*>(pa);
  // pv 现在指向了一个类型为A的对象
  ...
  pv = dynamic_cast<B*>(pb);
  // pv 现在指向了一个类型为B的对象
}

(2)

class BaseClass {
  public:
  int m_iNum;
  virtual void foo(){};
  //基类必须有虚函数。保持多台特性才能使用dynamic_cast
  };
  class DerivedClass: public BaseClass {
  public:
  char *m_szName[100];
  void bar(){};
  };
  BaseClass* pb = new DerivedClass();
  DerivedClass *pd1 = static_castDerivedClass *>(pb);
  //子类->父类,静态类型转换,正确但不推荐
  DerivedClass *pd2 = dynamic_castDerivedClass *>(pb);
  //子类->父类,动态类型转换,正确
  BaseClass* pb2 = new BaseClass();
  DerivedClass *pd21 = static_castDerivedClass *>(pb2);
  //父类->子类,静态类型转换,危险!访问子类m_szName成员越界
  DerivedClass *pd22 = dynamic_castDerivedClass *>(pb2);
  //父类->子类,动态类型转换,安全的。结果是NULL

3)const_cast<T*>(a)

  去掉类型中的常量,除了const或不稳定的变址数,T和a必须是相同的类型。表达式const_cast<T*>(a)被用于从一个类中去除以下这些属性:const, volatile, 和 __unaligned。

例子:

(1)

class A { ... };
void f()
{
 const A *pa = new A;//const对象
A *pb;//非const对象
//pb = pa; // 这里将出错,不能将const对象指针赋值给非const对象
pb = const_cast<A*>(pa); // 现在OK了
...
}

(2)

class A { ... };
void f()
{
 const A *pa = new A;//const对象
A *pb;//非const对象
//pb = pa; // 这里将出错,不能将const对象指针赋值给非const对象
pb = const_cast<A*>(pa); // 现在OK了
...
}

(3)

class A { ... };
void f()
{
 const A *pa = new A;//const对象
A *pb;//非const对象
//pb = pa; // 这里将出错,不能将const对象指针赋值给非const对象
pb = const_cast<A*>(pa); // 现在OK了
...
}

(4)

struct SA {
  int i;
  };
  const SA ra;
  //ra.i = 10; //直接修改const类型,编译错误
  SA &rb = const_castSA&>(ra);
  rb.i = 10;

4)reinterpret_cast<T*>(a)

 任何指针都可以转换成其它类型的指针,T必须是一个指针、引用、算术类型、指向函数的指针或指向一个类成员的指针。表达式reinterpret_cast<T*>(a)能够用于诸如char* 到 int*,或者One_class* 到 Unrelated_class*等类似这样的转换,因此可能是不安全的。

例子:

(1)

class A { ... };
class B { ... };
void f()
{
  A* pa = new A;
  void* pv = reinterpret_cast<A*>(pa);
  // pv 现在指向了一个类型为B的对象,这可能是不安全的
  ...
}

(2)

int doSomething(){return 0;};
  typedef void(*FuncPtr)();
  //FuncPtr is 一个指向函数的指针,该函数没有参数,返回值类型为 void
  FuncPtr funcPtrArray[10];
  //10个FuncPtrs指针的数组 让我们假设你希望(因为某些莫名其妙的原因)把一个指向下面函数的指针存入funcPtrArray数组:
  funcPtrArray[0] = &doSomething;
  // 编译错误!类型不匹配,reinterpret_cast可以让编译器以你的方法去看待它们:funcPtrArray
  funcPtrArray[0] = reinterpret_castFuncPtr>(&doSomething);
  //不同函数指针类型之间进行转换


4)总 结

  去const属性用const_cast。

  基本类型转换用static_cast。

  多态类之间的类型转换用daynamic_cast。

  不同类型的指针类型转换用reinterpreter_cast。


  • 本站(WWW.)旨在分享和传播互联网科技相关的资讯和技术,将尽最大努力为读者提供更好的信息聚合和浏览方式。
    本站(WWW.)站内文章除注明原创外,均为转载,整理或搜集自网络.欢迎任何形式的转载,转载请注明出处.
    转载请注明:文章转载自:[169IT-IT技术资讯]
    本文标题:标准c++四种强制类型转换方式介绍
相关文章推荐:


站内导航:


特别声明:169IT网站部分信息来自互联网,如果侵犯您的权利,请及时告知,本站将立即删除!

©2012-2021,,E-mail:www_#163.com(请将#改为@)

浙ICP备11055608号-3