您的位置:首页 > 编程语言 > C语言/C++

[C++基础]C++4个转型操作符——数据类型转换

2013-01-18 13:42 316 查看
static_cast:静态类型转换。用于基本数据类型之间的转换。 用法:static_cast <typeid> (expression)。 说明:该运算符把expression转换为typeid类型,但没有运行时类型检查来确保转换的安全性。 
dynamic_cast:动态类型转换。用在父/子类指针之间的互相转化;。用法:dynamic_cast < type-id > ( expression_r_r )。该运算符把expression_r_r转换成type-id类型的对象。Type-id必须是类的指针、类的引用或者void *;如果type-id是类指针类型,那么expression_r_r也必须是一个指针,如果type-id是一个引用,那expression_r_r也必须是一个引用。dynamic_cast主要用于类层次间的上行转换和下行转换,还可以用于类之间的交叉转换。在类层次间进行上行转换时,dynamic_cast和static_cast的效果是一样的;在进行下行转换时,dynamic_cast具有类型检查的功能,比static_cast更安全。用精炼的语言概括,就是专门用于面向对象中的down
cast的。但是有三点是前提:第一,必须用于类和子类之间的转换;第二,必须用于指针或引用类型的转换;第三,基类必须有虚函数。
const_cast:常量类型转换。把cosnt或volatile属性去掉。
   
reinterpret_cast:重新解释类型转换。用法:reinpreter_cast<type-id> (expression_r_r)。type-id必须是一个指针、引用、算术类型、函数指针或者成员指针。它可以把一个指针转换成一个整数,也可以把一个整数转换成一个指针(先把一个指针转换成一个整数,在把该整数转换成原类型的指针,还可以得到原先的指针值)。
//用法形式都是:xxx_cast<type>(express)
#pragma  once
#include <string>
#include <iostream>
#include <conio.h>
using namespace std;

//static_cast:基本拥有与C旧式转型相同的威力与意义,以及相同的限制。它用的最多,主要是在基本类型之间的转换
void test1()
{
int first=23,second=31;
double res=(double)first/second; //旧式C语法
double res2=static_cast<double>(first)/second;//新式C++转型符
cout<<res<<" "<<res2<<endl;// 0.741935 0.741935
// 	char* str="789";
// 	cout<<static_cast<int>(str)<<endl;//error:无法从char*转换为int
}
//const_cast:用来去掉表达式中的常量性(constness),常量属性多体现在指针和引用,因为如果没有指针和引用,就不存在不小心修改了不能修改的数据。
void test2()
{
int num=123;
const int* pNum=#
//int* pNum1=pNum;//errer:cannot convert from 'const int*' to 'int*'
int* pNum2=(int*)pNum; //旧式C
int* pNum3=const_cast<int*>(pNum);//新式C++ const_cast移除常量性
}
//dynamic_cast:用来执行继承体系中“安全的向下转型或跨系转型动作“,就是子类对象指针转化为父类对象指针。可以利用dynamic_cast将指向base classObject的pointer或reference转型为指向derived classObject的pointer或reference,如果转型失败,会以一个null指针(转换的是pointer的话)或一个exception表现出来(转换的是reference的话)
class B{public:virtual void fun(){cout<<"B.fun()"<<endl;}};
class D1:public B{public:void fun(){cout<<"D1.fun()"<<endl;}void fun2(){cout<<"D1.fun2()"<<endl;}};
class D2:public B{public:void fun(){cout<<"D2.fun()"<<endl;}void fun3(){cout<<"D2.fun3()"<<endl;}};
void test3()
{
//父类指针转换为子类指针时,父类要有虚函数
B* pb=new D2();
//pb->fun();//D2.fun()
D1* pd1=dynamic_cast<D1*>(pb);
if(pd1)pd1->fun2();//D2.fun()
D2* pd2=dynamic_cast<D2*>(pb);
if(pd2)pd2->fun3();//D2.fun3()

//子类指针转换为父类指针,不需要虚函数
class CBase{};//基类
class CDerived : public CBase{};//继承类
CDerived dc;
CDerived* dp=&dc;
CBase* cc1=dp;//老式:子类指针转换为父类指针,即父类指针指向子类对象
CBase* cb1=dynamic_cast<CBase*>(dp);//使用dynamic_cast将指向继承类的指针转化为指向基类的指针
printf("point: %d, %d, %d, %d",dp,cc1,cb1,&dc);//它们的地址相同,说明它们在内存中是同一个地址;即子类指针转换为父类指针,父类的地址指向子类的地址,且是相同的。

CBase& cc2=dc;
CBase& cb2=dynamic_cast<CBase&>(dc);//使用dynamic_cast将指向继承类的引用转化为指向基类的引用

}
//reinterpret_cast:最常用的用途是转化"函数指针"类型
typedef void (*funcPtr)();//funcPtr是个无参数返回值为void型的函数指针类型
int iFunc(){return 0;}//iFunc为一个无参数返回值为int的函数
void func(funcPtr f){}//func函数的参数是一个类型为funcPtr类型的函数指针
void test4()
{
//func(iFunc);//errer:不能将参数1从"int(_cdecl*)(void)"转换为"funcPtr";iFunc函数若是void iFunc(){};就行了
func(reinterpret_cast<funcPtr>(iFunc));//reinterpret_cast将返回值为int的函数转化为返回值为void的函数。但是传入的参数一定要相同
}
void test(char t)
{
cout<<"press key====="<<t<<endl;
switch (t)
{
case '1':test1();break;
case '2':test2();break;
case '3':test3();break;
case '4':test4();break;
case 27:
case 'q':exit(0);break;
default: cout<<"default "<<t<<endl;break;
}
}
int main()
{
while(1)
{
test(getch());
}
return 0;
}

 
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: