C++强制类型转换
合集下载
相关主题
- 1、下载文档前请自行甄别文档内容的完整性,平台不提供额外的编辑、内容补充、找答案等附加服务。
- 2、"仅部分预览"的文档,不可在线预览部分如存在完整性等问题,可反馈申请退款(可完整预览的文档不适用该条件!)。
- 3、如文档侵犯您的权益,请联系客服反馈,我们会尽快为您处理(人工客服工作时间:9:00-18:30)。
D *pd2 = dynamic_cast<D *>(pb); } 在上面的代码段中,如果 pb 指向一个 D 类型的对象,pd1 和 pd2 是一样的,并 且对这两个指针执行 D 类型的任何操作都是安全的; 但是,如果 pb 指向的是一个 B 类型的对象,那么 pd1 将是一个指向该对象的指 针,对它进行 D 类型的操作将是不安全的(如访问 m_szName), 而 pd2 将是一个空指针。 另外要注意:B 要有虚函数,否则会编译出错;static_cast 则没有这个限制。 这 是 由 于 运 行 时 类 型 检 查 需 要 运 行 时 类 型 信 息 ,而 这 个 信 息 存 储 在 类 的 虚 函 数 表 ( 关于虚函数表的概念,详细可见<Inside c++ object model>)中,只有定义了 虚函数的类才有虚函数表, 没有定义虚函数的类是没有虚函数表的。 另外,dynamic_cast 还支持交叉转换(cross cast)。如下代码所示。 class A{ public: int m_iNum; virtual void f(){} }; class B:public A{ }; class D:public A{ }; void foo(){ B *pb = new B; pb->m_iNum = 100; D *pd1 = static_cast<D *>(pb); //compile error D *pd2 = dynamic_cast<D *>(pb); //pd2 is NULL delete pb; } 在函数 foo 中,使用 static_cast 进行转换是不被允许的,将在编译时出错;而使 用 dynamic_cast 的转换则是允许的,结果是空指针。
static_cast 和 reinterpret_cast 操作符修改了操作数类型。它们不是互逆的; static_cast 在编译时使用类型信息执行转换,在转换执行必要的检测(诸如指针越界 计算, 类型检查). 其操作数相对是安全的。另一方面;reinterpret_cast 仅仅是重新 解释了给出的对象的比特模型而百度文库有进行二进制转换, 例子如下:
reinterpret_cast
reinterpret_cast 是 C++里的强制类型转换符。 操作符修改了操作数类型,但仅仅是重新解释了给出的对象的比特模型而没有进 行二进制转换。 例如:int *n= new int ; double *d=reinterpret_cast<double*> (n); 在进行计算以后, d 包含无用值. 这是因为 reinterpret_cast 仅仅是复制 n 的 比特位到 d, 没有进行必要的分析。 因此, 需要谨慎使用 reinterpret_cast. 并且:reinterpret_cast 只能在指针之间转换。 == =========================================== == static_cast .vs. reinterpret_cast == ================================================
dynamic_cast
用法:dynamic_cast < type-id > ( expression ) 该运算符把 expression 转换成 type-id 类型的对象。Type-id 必须是类的指针、 类的引用或者 void *; 如果 type-id 是类指针类型,那么 expression 也必须是一个指针,如果 type-id 是一个引用,那么 expression 也必须是一个引用。 dynamic_cast 主要用于类层次间的上行转换和下行转换,还可以用于类之间的 交叉转换。 在类层次间进行上行转换时,dynamic_cast 和 static_cast 的效果是一样的; 在进行下行转换时,dynamic_cast 具有类型检查的功能,比 static_cast 更安全。 class B{ public: int m_iNum; virtual void foo(); }; class D:public B{ public: char *m_szName[100]; }; void func(B *pb){ D *pd1 = static_cast<D *>(pb);
reinterpret_cast 是为了映射到一个完全不同类型的意思,这个关键词在我们需 要 把 类 型 映 射 回 原 有 类 型 时 用 到 它 。我 们 映 射 到 的 类 型 仅 仅 是 为 了 故 弄 玄 虚 和 其 他 目 的,这是所有映射中最危险的。(这句话是 C++编程思想中的原话)
const_cast
用法:const_cast<type_id> (expression) 该运算符用来修改类型的 const 或 volatile 属性。除了 const 或 volatile 修饰之 外, type_id 和 expression 的类型是一样的。 一、常量指针被转化成非常量指针,并且仍然指向原来的对象; 二、常量引用被转换成非常量引用,并且仍然指向原来的对象; 三、常量对象被转换成非常量对象。 Voiatile 和 const 类试。举如下一例: class B{ public: int m_iNum; } void foo(){ const B b1; b1.m_iNum = 100; //comile error B b2 = const_cast<B>(b1); b2. m_iNum = 200; //fine } 上面的代码编译时会报错,因为 b1 是一个常量对象,不能对它进行改变; 使用 const_cast 把它转换成一个非常量对象,就可以对它的数据成员任意改变。 注意:b1 和 b2 是两个不同的对象。
int i; float f = 166.7f; i = static_cast<int>(f); 此时结果,i 的值为 166。 2、C++中的 reinterpret_cast 主要是将数据从一种类型的转换为另一种类型。所 谓“通常为操作数的位模式提供较低层的重新解释”也就是说将数据以二进制存在形式 的重新解释。比如: int i; char *p = "This is a example."; i = reinterpret_cast<int>(p); 此时结果,i 与 p 的值是完全相同的。reinterpret_cast 的作用是说将指针 p 的值 以二进制(位模式)的方式被解释为整型,并赋给 i,一个明显的现象是在转换前后 没有数位损失。
int n=9; double d=static_cast < double > (n); 上面的例子中, 我们将一个变量从 int 转换到 double。 这些类型的二进制表达 式是不同的。 要将整数 9 转换到 双精度整数 9,static_cast 需要正确地为双精度 整数 d 补足比特位。其结果为 9.0。而 reinterpret_cast 的行为却不同: int n=9; double d=reinterpret_cast<double & > (n); 这次, 结果有所不同. 在进行计算以后, d 包含无用值. 这是因为 reinterpret_c ast 仅仅是复制 n 的比特位到 d, 没有进行必要的分析. 因此, 你需要谨慎使用 reinterpret_cast.
static_cast
用法:static_cast < type-id > ( expression ) 该运算符把 expression 转换为 type-id 类型,但没有运行时类型检查来保证转换 的安全性。它主要有如下几种用法: ①用于类层次结构中基类和子类之间指针或引用的转换。 进行上行转换(把子类的指针或引用转换成基类表示)是安全的; 进 行 下 行 转 换( 把 基 类 指 针 或 引 用 转 换 成 子 类 表 示 )时 ,由 于 没 有 动 态 类 型 检 查 , 所以是不安全的。 ②用于基本数据类型之间的转换,如把 int 转换成 char,把 int 转换成 enum。这 种转换的安全性也要开发人员来保证。 ③把空指针转换成目标类型的空指针。 ④把任何类型的表达式转换成 void 类型。 注意:static_cast 不能转换掉 expression 的 const、volitale、或者__unaligned 属性。 C++中 static_cast 和 reinterpret_cast 的区别 C++primer 第五章里写了编译器隐式执行任何类型转换都可由 static_cast 显示 完成;reinterpret_cast 通常为操作数的位模式提供较低层的重新解释 1、C++中的 static_cast 执行非多态的转换,用于代替 C 中通常的转换操作。因 此,被做为隐式类型转换使用。比如: