c++强制转型
2017-06-25 20:32
141 查看
##const_cast<T*>(a)
它用于从一个类中去除以下这些属性:const、volatile和__unaligned。
calss A{ // ...}
void Function()
{
const A *pConstObj = new A;
A *pObj = pConstObj;//ERROR:不能将const对象指针赋值给非const对象
pObj = const_cast<A*>{ pConstObj};//ok
}
这种强制转型的目的简单明确,使用情形比较单一,易于掌握。
##dynamic_cast<T*>(a)
它将a值转换成类型为T的对象指针,主要用来实现类层次结构的提升,在很多书中它被称作“安全的向下转型(Safe Downcasting)”,用于继承体系中的向下转型,将基类指针转换为派生类指针,这种转换较为严格和安全。如下面的代码片段所示:
class B{...};
class D : public B{//...};
void Function(D *pObjD)
{x
D *pObj = dynamic_cast<D*>(pobjD);
//...
}
如果pObjD指向一个D类型的对象,pObj则指向该对象,所以对该指针指向D类型的任何操作都是安全的。但是,如果pObjD指向
的是一个B类型的对象,pObj将是一个空指针,这在一定程度上保证了程序员所需要的“安全”,只是,它也付出了一定的运行时代价,而且代价非常大,实现相当慢。有一种通用实现是通过对类名称进行字符串比较来实现的,只是其在继承体系中所处的位置越深,对strcmp的调用越多,带价也就越大。如果应用对性能要求较高,那么请放弃dynamic_cast。
##reinterpret_cast<T*>(a)
它能够用于诸如One_class* 到 Unrelated_class*这样的不相关类型之间的转换,因此它是不安全的。其与C风格的强制转型很是相似。
class A { // ...};
class B { // ...};
void f()
{
A* pa = new A;
B* pb = reinterpret_cast<B*>(pa);
//...
}
在不了解A、B内存布局的情况下,强行将其进行转换,很有可能出现内存膨胀或截断。
##static_cast<T*>(a)
它将a的值转换为模版中指定的类型T。但是,在运行时转换过程中,他不会进行类型检查,不能确保转换的安全性。如以下代码片段所示:
class B{...}
class D : public B{...}
void Function(B* pb,D* pd)
{
D* pd2 = static_cast<D*>(pb);//不安全
B* pb2 = static_cast<B*>(pd);//安全的
}
之所以说第一种是不安全的,是因为如果pb指向的仅仅是一个基类B的对象,那么就会凭空生成继承信息。至于这些信息是什么、正确与否,无从得知。所以对它进行D类型的操作将是不安全的。
C++是一种强类型的编程语言,其规则设计为“保证不会发生类型错误”。在理论层面上,如果希望程序顺利地通过编译,就不应该试图对任何对象做任何不安全的操作。不幸的是,继承自C语言的强制转型破坏了类型系统,所以建议尽量少的使用强制转型,无论是旧的C风格的还是新的C++风格。如果发现自己是用了强制转型,那么一定要小心,这可能就是程序出现的一个信号。
##请记住: 由于强制转型无所不能,会给C++程序带来很大的安全隐患,因此建议在C++代码中,努力将强制转型减到最少。
转自《编写高质量代码——改善C++程序的150个建议》
它用于从一个类中去除以下这些属性:const、volatile和__unaligned。
calss A{ // ...}
void Function()
{
const A *pConstObj = new A;
A *pObj = pConstObj;//ERROR:不能将const对象指针赋值给非const对象
pObj = const_cast<A*>{ pConstObj};//ok
}
这种强制转型的目的简单明确,使用情形比较单一,易于掌握。
##dynamic_cast<T*>(a)
它将a值转换成类型为T的对象指针,主要用来实现类层次结构的提升,在很多书中它被称作“安全的向下转型(Safe Downcasting)”,用于继承体系中的向下转型,将基类指针转换为派生类指针,这种转换较为严格和安全。如下面的代码片段所示:
class B{...};
class D : public B{//...};
void Function(D *pObjD)
{x
D *pObj = dynamic_cast<D*>(pobjD);
//...
}
如果pObjD指向一个D类型的对象,pObj则指向该对象,所以对该指针指向D类型的任何操作都是安全的。但是,如果pObjD指向
的是一个B类型的对象,pObj将是一个空指针,这在一定程度上保证了程序员所需要的“安全”,只是,它也付出了一定的运行时代价,而且代价非常大,实现相当慢。有一种通用实现是通过对类名称进行字符串比较来实现的,只是其在继承体系中所处的位置越深,对strcmp的调用越多,带价也就越大。如果应用对性能要求较高,那么请放弃dynamic_cast。
##reinterpret_cast<T*>(a)
它能够用于诸如One_class* 到 Unrelated_class*这样的不相关类型之间的转换,因此它是不安全的。其与C风格的强制转型很是相似。
class A { // ...};
class B { // ...};
void f()
{
A* pa = new A;
B* pb = reinterpret_cast<B*>(pa);
//...
}
在不了解A、B内存布局的情况下,强行将其进行转换,很有可能出现内存膨胀或截断。
##static_cast<T*>(a)
它将a的值转换为模版中指定的类型T。但是,在运行时转换过程中,他不会进行类型检查,不能确保转换的安全性。如以下代码片段所示:
class B{...}
class D : public B{...}
void Function(B* pb,D* pd)
{
D* pd2 = static_cast<D*>(pb);//不安全
B* pb2 = static_cast<B*>(pd);//安全的
}
之所以说第一种是不安全的,是因为如果pb指向的仅仅是一个基类B的对象,那么就会凭空生成继承信息。至于这些信息是什么、正确与否,无从得知。所以对它进行D类型的操作将是不安全的。
C++是一种强类型的编程语言,其规则设计为“保证不会发生类型错误”。在理论层面上,如果希望程序顺利地通过编译,就不应该试图对任何对象做任何不安全的操作。不幸的是,继承自C语言的强制转型破坏了类型系统,所以建议尽量少的使用强制转型,无论是旧的C风格的还是新的C++风格。如果发现自己是用了强制转型,那么一定要小心,这可能就是程序出现的一个信号。
##请记住: 由于强制转型无所不能,会给C++程序带来很大的安全隐患,因此建议在C++代码中,努力将强制转型减到最少。
转自《编写高质量代码——改善C++程序的150个建议》
相关文章推荐
- C++的四种强制转型形式
- C++四种强制转型
- C++箴言:将强制转型减到最少
- C++结构类型在GDB中的强制类型转换(带namespace的强制转型要加单引号的)
- 改善C++ 程序的150个建议学习之建议24:尽量采用C++风格的强制转型
- C++的四种强制转型形式
- C++RTTI强制转型
- C++的四种强制转型形式
- 改善C++ 程序的150个建议学习之建议11:将强制转型减到最少
- 改善C#程序的50种方法 条款3:操作符is或as优于强制转型
- C++:单继承与转型
- C++中的类型强制转换
- C/C++ 误区:强制转换 malloc() 的返回值
- 强制转型和类型转换
- C/C++ 误区四:强制转换 malloc() 的返回值
- C++编程习惯:尽量少做转型动作
- c++ 强制转换
- c++强制转换类型
- [转载] 标准C++的四种强制转换类型运算符
- 条款3:操作符is或as优于强制转型