找回密码
 立即注册
  • QQ空间
  • 回复
  • 收藏

【C++九十七】C++中的类型转换

admin 2019-8-11 12:50 102人围观 C++相关

 依法编程 Autocodes  

欢迎各位小伙伴关注”依法编程“,一起交流

一、C++中的四种类型转换操作符


在C语言中,有强制类型转换,不管什么类型,格式统一:

TYPE  b = (TYPE)a

但在C++中,C++风格的类型转换提供了4种类型转换操作符来应对不同场合的应用。

【1】static_cast  静态类型转换。如int转换成char;

【2】reinterpret_cast  重新解释类型;

【3】dynamic_cast  动态类型转换。如子类和父类之间的多态类型转换;

【4】const_cast    去const属性;

C++中4种类型转换的格式:

TYPE b = static_cast<TYPE>(a)

二、static_cast<>() 使用


#include<iostream>

using namespace std;

void main()

{

double dpi=3.1415926;

//C语言

int num1=(int)dpi;

//C++

//静态类型转换

int num2=static_cast<int>(dpi);

//隐式类型转换

int num3=dpi;

//static_cast<>()不能用于指针转换

char* p1="hello world";

int* p2=NULL;

//使用static_cast<>() 编译器会做类型检查

//p2=static_cast<int*>(p1); //错误

system("pause");

}

1、static_cast静态类型转换,编译时C++编译器会做类型检查,基本数据类型能转换,但是不能转换指针;

2、C语言中,能隐式类型转换的,在C++中可用static_cast<>()进行类型转换;

三、reinterpret_cast<>() 使用


#include<iostream>

using namespace std;

void main()

{

////static_cast<>()不能用于指针转换

char* p1="hello world";

int* p2=NULL;

////使用static_cast<>() 编译器会做类型检查

////p2=static_cast<int*>(p1); //错误

p2=reinterpret_cast<int*>(p1);

cout<<"p1:"<<p1<<endl;//输出字符串 %s

//p2是int*数据类型,打印首地址 %d

cout<<"p2:"<<p2<<endl;//

system("pause");

}

1、若不同类型之间,进行强制类型转换,用reinterpret_cast<>()进行重新解释;

2、reinterpret_cast<>()很难保证移植性;

3、C语言中不能隐式类型转换的,在C++中可以用reinterpret_cast<>()进行强制类型解释;

4、static_cast<>()和reinterpreter_cast<>()基本上把C语言中的强制类型转换给覆盖了;

四、dynamic_cast<>() 使用


先看一下之前多态的程序:

#include<iostream>

using namespace std;

//基类

class Animal

{

public:

virtual void cry()=0;//纯虚函数

};

//派生类一

class Dog:public Animal

{

public:

virtual void cry()

{

cout<<"汪汪!"<<endl;

}

void doHome()

{

cout<<"看家!"<<endl;

}

};

//派生类二

class Cat:public Animal

{

public:

virtual void cry()

{

cout<<"喵喵!"<<endl;

}

void doThing()

{

cout<<"抓老鼠!"<<endl;

}

};

void playObj(Animal *base)

{

base->cry();//根据传递类型的不同实现多态

}

void main()

{

Dog d1;

Cat c1;

playObj(&d1);//实现多态

playObj(&c1);

system("pause");

}

之前的程序中,我们定义一个指向基类的指针,调用playObj函数时,传递不同的子类对象,将子类对象赋给基类指针,实现多态。

我现在想在函数playObj中能够对传递的子类对象进行类型识别,根据传递的类型不同去调用不同子类的函数。比如,我传递过来Dog类的对象或者Cat类型的对象,我能够进行判断,根据我的判断结果然后去执行不同类的函数。

(一)dynamic_cast<>() 语法


dynamic_cast <type-id> (expression)

该运算符把expression转换成type-id类型的对象。Type-id 必须是类的指针、类的引用或者void*;

如果 type-id 是类指针类型,那么expression也必须是一个指针,如果 type-id 是一个引用,那么 expression 也必须是一个引用。

(二)dynamic_cast<>() 规则


dynamic_cast运算符可以在执行期决定真正的类型。

通常是向下转换,也就是基类到派生类,运行时程序会检查expression是不是与type-id类型兼容,如果是,表达式就返回一个派生类地址,然后转换成tppe-id类型,否则返回一个NULL。

在进行下行转换时,dynamic_cast具有类型检查的功能,比static_cast更安全。

(三)dynamic_cast<>() 程序案例


#include<iostream>

using namespace std;

//基类

class Animal

{

public:

virtual void cry()=0;//纯虚函数

};

//派生类一

class Dog:public Animal

{

public:

virtual void cry()

{

cout<<"汪汪!"<<endl;

}

void doHome()

{

cout<<"看家!"<<endl;

}

};

//派生类二

class Cat:public Animal

{

public:

virtual void cry()

{

cout<<"喵喵!"<<endl;

}

void doThing()

{

cout<<"抓老鼠!"<<endl;

}

};

void playObj(Animal *base)

{

//dynamic_cast 运行时类型识别

//父类对象==》子类对象

//向下转型

//将base类型转换成Dog*类型

//如果转换失败,返回NULL

Dog *pDog=dynamic_cast<Dog*>(base);

if(pDog!=NULL)

{

pDog->doHome();//让狗狗做自己特有的工作

}

//将base类型转换成Cat*类型

//如果转换失败,返回NULL

Cat *pCat=dynamic_cast<Cat*>(base);

if(pCat!=NULL)

{

pCat->doThing();//让猫咪做自己特有的工作

}

}

void main()

{

Dog d1;

Cat c1;

playObj(&d1);//看家

playObj(&c1);//抓老鼠

system("pause");

}

五、const_cast<>() 使用


const可以修饰指针变量,也可以修饰指针指向的内存空间。

const_cast<>(),去除变量的只读属性;

下面程序中,指针p指向的内存空间定义为const,不可修改,但通过const_cast类型转换,通过p1进行了修改。

#include<iostream>

using namespace std;

//p指向的内存空间只读

void PrintBuf(const char *p)

{

//p[0]='Z';//错误

cout<<p<<endl;

//从const char* 转换到char*

char *p1=const_cast<char*>(p);

p1[0]='Z';

cout<<p<<endl;//通过p1修改了内存空间

}

void main()

{

char buf[]="abcdefg";

PrintBuf(buf);

system("pause");

}

但是,并不是所有的const都可以通过const_cast去const修改,比如const常量是不能修改的,即使const_cast也不能修改。

#include<iostream>

using namespace std;

//p指向的内存空间只读

void PrintBuf(const char *p)

{

//常量

char *p2=const_cast<char*>(p);

//p2[0]='Z';  //运行中断

cout<<p<<endl;//通过p1修改了内存空间

}

void main()

{

char buf[]="abcdefg";//分配了内存

char *mybuf="abcdefg";//指针指向的内存空间是常量,没有分配内存

PrintBuf(mybuf);

system("pause");

}

常量是固定值,在程序执行期间不会改变。这些固定的值,又叫做字面量。





----------------------------------------------------------------------------------------------------------------------
我们尊重原创,也注重分享,文章来源于微信公众号:依法编程,建议关注公众号查看原文。如若侵权请联系qter@qter.org。
----------------------------------------------------------------------------------------------------------------------

鲜花

握手

雷人

路过

鸡蛋

yafeilinux和他的朋友们微信公众号二维码

微信公众号

专注于Qt嵌入式Linux开发等。扫一扫立即关注。

Qt开源社区官方QQ群二维码

QQ交流群

欢迎加入QQ群大家庭,一起讨论学习!

我有话说......