C++ 四种类型转换
2016-04-05 10:44
525 查看
C++ 四种类型转换
<span style="font-size:18px;"><span style="font-size:18px;">#include<iostream> #include<vector> #include<string> using namespace std; /* static_cast: 用法:static_cast < type-id > ( expression ) 该运算符把expression转换为type-id类型,但没有运行时类型检查来保证转换的安全性。它主要有如下几种用法: ①用于类层次结构中基类(父类)和派生类(子类)之间指针或引用的转换。static_cast static_cast 进行上行转换(把派生类的指针或引用转换成基类表示,对象也可以)是安全的; 进行下行转换(把基类指针或引用转换成派生类表示)时,由于没有动态类型检查,所以是不安全的,无任何效果 ②用于基本数据类型之间的转换,如把int转换成char,把int转换成enum。这种转换的安全性也要开发人员来保证。 ③把空指针转换成目标类型的空指针。 ④把任何类型的表达式转换成void类型。 */ /* dynamic_cast: 用法:dynamic_cast < type-id > ( expression ) type-id 必须是个多态类型,即必须要含有虚函数,类中有虚表才能存储 运行时类别信息。 该运算符把expression转换成type - id类型的对象。Type - id必须是类的指针、类的引用或者void*; 如果type - id是类指针类型,那么expression也必须是一个指针,如果type - id是一个引用,那么expression也必须是一个引用。 dynamic_cast运算符可以在执行期决定真正的类型。如果downcast是安全的(也就说,如果基类指针或者引用确实指向一个派生类对象)这个运算符会传回适当转型过的指针。如果downcast不安全,这个运算符会传回空指针(也就是说,基类指针或者引用没有指向一个派生类对象)。 dynamic_cast主要用于类层次间的上行转换和下行转换,还可以用于类之间的交叉转换。 在类层次间进行上行转换时,dynamic_cast和static_cast的效果是一样的; 在进行下行转换时,dynamic_cast具有类型检查的功能,比static_cast更安全。 */ /* const_cast 用法:const_cast < type-id > ( expression ) 该操作符用于改变const和volatile,const_cast最常用的用途就是删除const属性,如果某个变量在大多数时候是常量,而在某个时候又是需要修改的,这时就可以使用const_cast操作符了。但是不能改变其值类型,只能改变属性。 */ /* reinterpret_cast<type-id> (expression) type-id 必须是一个指针、引用、算术类型、函数指针或者成员指针。它可以把一个指针转换成一个整数,也可以把一个整数转换成一个指针(先把一个指针转换成一个整数,再把该整数转换成原类型的指针,还可以得到原先的指针值)。 操作符修改了操作数类型,但仅仅是重新解释了给出的对象的比特模型而没有进行二进制转换。 reinterpret_cast是为了映射到一个完全不同类型的意思,这个关键词在我们需要把类型映射回原有类型时用到它。我们映射到的类型仅仅是为了故弄玄虚和其他目的,这是所有映射中最危险的。(这句话是C++编程思想中的原话) */ class X { public: virtual void Print() { puts("X"); } }; class A :public X { public: virtual void Print() { puts("A"); } }; class B :public X { public: virtual void Print() { puts("B"); } }; /* X / \ A B */ class F { public: virtual void Print() { puts("F"); } }; class G:public F { public: virtual void Print() { puts("G"); } }; int main(void) { X x; A a; B b; F f; G g; X* px =nullptr; A* pa = nullptr; B* pb = nullptr; F* pf = nullptr; G* pg = nullptr; puts("----------static_cast---------------"); int i1 = 0; double dou1 = 3.66; cout << "i1: " << static_cast<int>(dou1)<<endl; //多态 子类向父类转换 px = static_cast<X*>(&a); px->Print();//A //非多态 子类向父类转换 pg = static_cast<G*>(&f); pg->Print();//F //多态 父类向子类转换(无任何作用) pa = static_cast<A*>(&x); pa->Print();//X //非多态 父类向子类转换(无任何作用) pa = static_cast<A*>(&x); pa->Print();//X //多态 子类向父类转换(无任何作用) pf = static_cast<F*>(&g); pa->Print();//X //不相关类类型强转(无任何作用) pa = (A*)(&b); pa->Print(); //pa = static_cast<A*>(&b); 不相关自定义类型转换(报错) x = static_cast<X>(a); x.Print();//B puts("----------dynamic_cast---------------"); //pa->Print(); pa指向了B 转换之后也是指向B px = dynamic_cast<X*>(pa); if (nullptr != px) { px->Print();//B } pa = dynamic_cast<A*>(px);//得到空指针 if (nullptr != pa) { pa->Print(); } A a1; A& refA = a1; X& refX = dynamic_cast<X&>(a1); refX.Print();// A 反过来会产生异常 puts("----------const_cast---------------"); char c = 'A'; int k = 1; char* pC = reinterpret_cast<char*>(&k); short* pS= reinterpret_cast<short*>(&k); printf("char* %p\n", &c); printf("int*: %p\n",&k); printf("reinterpret_cast char*%p\n",pC); printf("reinterpret_cast short*:%p\n", pS); printf("char* %p\n", &c+1); printf("int*: %p\n", &k+1); printf("reinterpret_cast char*%p\n", pC+1); printf("reinterpret_cast short*:%p\n", pS+1); int* p1 = &k; printf("int*: %d\n", p1); ++p1; printf("int*: %d\n", p1); p1 = reinterpret_cast<int*>('A'); cout << p1 << endl;//00000041 将一个整数转换为指针 char ch = (char)(p1); cout << ch << endl;//A 再转换回来可以得到同样的值 return 0; }</span></span>
相关文章推荐
- sublime text2 C++编译环境配置
- c++ string 扩展函数
- C++中二维数组的参数传递
- [C/C++]_[初级]_[原子操作1]
- [C/C++]_[初级]_[原子操作]
- C++命名空间
- 使用 CJSON 在C语言中进行 JSON 的创建和解析的实例讲解
- C++基类和派生类的赋值
- 贪吃蛇小游戏 C++实现
- C/C++连接MySql数据库
- [C++基础]随机数,随机种子数
- C++继承时的对象模型
- 单链表的插入问题
- C++解析UTF8字符流转换
- C++基础实践一之旱冰场造价
- C语言函数sscanf()的用法
- memcpy函数用法
- memset()函数及其作用
- Java and C++
- windows下 boost库的安装