,,C++中的类型转换static_cast、dynamic_cast、const_cast和reinterpret_cast总结

,,C++中的类型转换static_cast、dynamic_cast、const_cast和reinterpret_cast总结

本文主要介绍c中类型转换static_cast、dynamic_cast、const_cast、reinterpret_cast的总结,有需要的朋友可以参考一下。

前言

本文总结了c中的类型转换,有时候我不太关注这些小知识点,但是在实际开发中经常用到。俗话说,不懂自己代码的程序员不是好程序员;如果一个程序员对自己的代码一无所知,只知道傻乎乎地用,总有一天,你会迷失自我。

C #中有两种类型的类型转换:

1.隐式类型转换;

2.显式类型转换。

对于隐式转换,它是标准转换。在很多情况下,它是在不经意间发生的。例如,当添加int类型和float类型时,int类型将隐式转换为float类型,然后执行加法操作。隐式转换不是今天总结的重点,而是显式转换。标准c中有四种类型转换器:static_cast、dynamic_cast、const_cast和reinterpret _ cast;下面将一一总结。

static_cast

static_cast的转换格式:static_cast type-id(表达式)

将expression转换为type-id主要用于非多态类型之间的转换,不提供运行时检查来保证转换的安全性。主要用于以下情况:

1.用于类层次结构中基类和子类之间指针和引用的转换;

当进行向上转换时,即子类的指针或引用转换为父类的表示时,这种转换是安全的;

向下转换时,即把父类的指针或引用转换成子类的表示,这种转换是不安全的,也需要程序员的保证;

2.用于基本数据类型之间的转换,比如将int转换成char,将int转换成enum等。这种转换的安全性需要程序员来保证;

3.将void指针转换为目标类型的指针是极其不安全的;

注意:static_cast不能转换表达式的const、volatile和__unaligned属性。

dynamic_cast

dynamic_cast的转换格式:dynamic_cast type-id(表达式)

将expression转换为type-id,必须是指向类的指针、对类的引用或void *;如果type-id是指针类型,那么expression也必须是指针;如果type-id是引用,那么expression也必须是引用。

Dynamic_cast主要用于类之间的上转换和下转换,也可以用于类之间的交叉转换。在类之间转换时,dynamic_cast和static_cast的效果是相同的。在下行转换中,dynamic_cast有类型检查的功能,比static_cast更安全。多态类型之间的转换主要使用dynamic_cast,因为类型提供运行时信息。我将在以下场合总结dynamic_cast的使用:

1.最简单的上行链路转换

例如,B继承自A,B转换为A,因此对于上行转换是安全的,如下所示:

复制代码如下:

#包括iostream

使用命名空间std

A级

{

//.

};

B类:公共A

{

//.

};

int main()

{

B *pB=新B;

a * pA=dynamic _ castA *(pB);//安全并且会成功

}

2.多个继承之间的向上转换

c继承B,B继承A,是多重继承关系;但是,关系很清楚,使用dynamic_cast进行转换时,也很简单:

复制代码如下:

A级

{

//.

};

B类:公共A

{

//.

};

C类:公共B类

{

//.

};

int main()

{

C *pC=新C;

b * pB=dynamic _ castB *(pC);//好的

a * pA=dynamic _ castA *(pC);//好的

}

上面的转换,static_cast和dynamic_cast的效果是一样的。并且这种上行转换也称为隐式转换;比如我们在定义变量的时候经常这样写:B * pB=new C;除了添加了一个dynamic_cast转换器之外,这与上面的相同。

3.转换为void *

您可以将类转换为void *,例如:

复制代码如下:

A级

{

公共:

虚拟void f(){}

//.

};

B类

{

公共:

虚拟void f(){}

//.

};

int main()

{

A *pA=新A;

B *pB=新B;

void * pV=dynamic _ cast void *(pA);//pV指向的对象

pV=dynamic _ cast void *(pB);//pV指向B的一个对象

}

但是虚函数必须包含在A类和b类中,为什么呢?因为类中有虚函数,意味着它希望基类的指针或引用指向派生类的对象,然后转换才有意义;因为运行时类型检查需要运行时类型信息,而这些信息存储在类的虚函数表中,所以只有定义虚函数的类才有虚函数表。

4.如果expression是type-id的基类,那么使用dynamic_cast进行转换时,会在运行时检查expression是否真的指向type-id的对象,如果是,就可以正确转换得到相应的值;否则,返回NULL如果是引用,运行时会抛出异常;例如:

复制代码如下:

B类

{

虚拟void f(){ };

};

D类:公共B类

{

虚拟void f(){ };

};

void main()

{

B* pb=新D;//不清楚但还可以

B* pb2=新B;

d * PD=dynamic _ castD *(Pb);//好的:pb其实指向一个D

d * pd2=dynamic _ castD *(Pb2);//pb2指向a B不是a D,现在pd2为空

}

这是从基类指针到派生类指针的向下转换。

对于一些复杂的继承关系,使用dynamic_cast进行转换存在一些陷阱;例如,有如下结构:

d型可以安全的转换成b型和c型,但是如果d型直接转换成a型呢?

复制代码如下:

A级

{

虚拟void Func()=0;

};

B类:公共A

{

void Func(){ };

};

C类:公共A

{

void Func(){ };

};

D类:公共B、公共C

{

void Func(){}

};

int main()

{

D *pD=新D;

a* pA=dynamic _ castA *(pD);//你会得到一个空的pA

}

如果你做上面的直接转移,你会得到一个空的pA指针;这是因为B和C都继承了A,都实现了虚函数func,导致无法决定A应该转换成哪个。正确的做法是:

复制代码如下:

int main()

{

D *pD=新D;

b * pB=dynamic _ castB *(pD);

a * pA=dynamic _ castA *(pB);

}

也就是我在实现QueryInterface时获取IUnknown的指针时,用的是* PPV=static _ castIX *(this);而不是* PPV=static _ cast unknown *(this);

在多重继承的情况下,从派生类转移到父类的父类时要特别注意。例如,有以下几种情况:

现在,你有一个A类型的指针,它指向实例E。你如何得到一个B类型的指针,它指向实例E?如果直接做翻译,编译器会有差异。不知道是走E-C-B还是E-D-B,这种情况下首先要把A类型的指针向下转换得到E类型的指针,然后指定一个正确的路线向上转换。

以上是关于dynamic_cast转换的一些细节,特别是对于多重继承的情况。在实际项目中,很容易出现问题。

const_cast

const_cast的转换格式:const_cast type-id(表达式)

Const_cast用于移除类型的Const、volatile和__unaligned属性。Const指针转换为非常数指针,仍然指向原始对象;常量引用被转换为非常量引用,而原始对象仍被引用。请看下面的代码示例:

复制代码如下:

/*

**文件名:ConstCastDemo

**作者:杰利扬

**日期:2013年12月27日

**描述:更多信息,请到https://www.jb51.net

*/

#包括iostream

使用命名空间std

CA级

{

公共:

CA():m_iA(10){}

int m _ iA

};

int main()

{

const CA *pA=新CA;

//pA-m _ iA=100;//错误

CA * pB=const _ cast CA *(pA);

p B- m _ iA=100;

//现在pA和pB指向同一个对象

cout pa-m _ iAendl;

cout Pb-m _ iAendl;

const CA a=* pA

//a . m _ iA=200;//错误

CA b=const _ cast CA(a);

p B- m _ iA=200;

//现在a和b引用同一个对象

coutb.m _ iAendl

couta.m _ iAendl

}

注意:不能通过在非指针和非引用变量上使用const_cast操作符来直接删除它的const、volatile和__unaligned属性。

reinterpret_cast

reinterpret_cast的转换格式:reinterpret _ cast type-id(表达式)

允许将任何指针类型转换为其他指针类型;听起来很厉害,但也不靠谱。它主要用于将一种数据类型从一种类型转换为另一种类型。它可以将指针转换成整数,也可以将整数转换成指针。在实际开发中,先将一个指针转换成一个整数,再将整数转换成原始指针,就可以得到原始指针值。特别是,它打开了系统的全局内存空间。当它需要在多个应用程序中使用时,它需要相互共享。当这个内存空间的指针经过时,可以将指针转换成整数值,然后将整数值转换成指针进行相应的操作。

总结

这篇博文总结了C中的类型转换,重点是显式转换。详细描述了C支持的四种显式转换。如果你有什么要补充的,或者我的总结有什么不对的地方,请给我们提意见。

郑重声明:本文由网友发布,不代表盛行IT的观点,版权归原作者所有,仅为传播更多信息之目的,如有侵权请联系,我们将第一时间修改或删除,多谢。

相关文章阅读

  • vs2015打包安装程序,vs2015程序打包,VS2022实现VC++打包生成安装文件图文详细历程
  • vc++6.0的快捷键,vc 快捷键
  • vc++6.0的快捷键,vc 快捷键,VC6.0常用快捷键大全
  • 绘制圆角矩形的方法,c++ 画矩形,C#画圆角矩形的方法
  • 懒汉式和饿汉式代码,单列模式懒汉和饿汉,C++单例模式的懒汉模式和饿汉模式详解
  • 好用的C++编译器,c++编译软件哪个好
  • semaphore c#,c++ semaphore
  • semaphore c#,c++ semaphore,C++中Semaphore内核对象用法实例
  • dev-c++使用教程,dev c++安装教程
  • dev-c++使用教程,dev c++安装教程,Dev C++ 安装及使用方法(图文教程)
  • C里面指针常量和常量指针的区别,c++指针常量和常量指针
  • C里面指针常量和常量指针的区别,c++指针常量和常量指针,简单总结C++中指针常量与常量指针的区别
  • com组件初始化失败,c#开发com组件,C++中COM组件初始化方法实例分析
  • c++静态成员变量使用,c++静态成员函数和静态成员变量
  • c++静态成员变量使用,c++静态成员函数和静态成员变量,详解c++ 静态成员变量
  • 留言与评论(共有 条评论)
       
    验证码: