C++ 的强制类型转换

news2024/11/15 10:53:35

C++ 的强制类型转换

目录(转换方式):

1 、static_cast

2 、dynamic_cast

3、reinterpret_cast

4、const_cast

5、类型转换使用建议

一、 static_cast: 用于基本类型之间的转换

static_cast<>() 可以说是神通广大。

使用方法 : type y = static_cast< type >( expression );

// type-> 需要转换成的目标类型
// expression -> 需要转换的变量或者表达式
//1、基本类型的转化
int age = 100;
double age1=static_cast< double >( age ); //将 int类型转换成 double

//2、父子类之间的转换   class Dog 继承至 class animal
Dog *dog1=new Dog();
Animal *al=static_cast<Animal *>(dog1);  //之类性转换成父类型
Dog *dog1=static_cast<Dog *>(al);   //父类型的指针到子类的指针(父类到子类有风险)

Dog dog2;
Animal &a2=static_cast<Animal &>(dog2); //之类性转换成父类型
Dog &dog2=static_cast<Dog &>(a2);      //父类型的引用到子类的引用(父类到子类有风险)

// 3、把空指针转换成目标类型的空指针
int *p=static_cast<int *>(NULL);
Dog *dog=static_cast<Dog*>(NULL);

// 4、把任何类型的表达式转换成void类型
int *p=new int[19];
void *vp=static_cast<void *>(p);
vp=p;

常见的基本数据类型:

  • 整数类型(int):用于表示整数,包括正整数、负整数和零。

  • 浮点数类型(float和double):用于表示实数,即带有小数点的数。

  • 字符类型(char):用于表示单个字符,可以是字母、数字、符号等。

  • 布尔类型(bool):用于表示真或假、是或否等。

使用时的陷阱:

1、static_cast : 可以用于类的上下转型。但是,这种转换方式没有运行时检查,因此可能会导致安全问题。

2、static_cast不能转换掉表达式的const、volatile或unaligned属性。如果需要改变这些属性,需要考虑其他类型的转换或使用方法。

二、 dynamic_cast 用于类之间的上下转型

dynamic_cast 主要用于实现多态性,通过基类的指针或引用来调用派生类的成员函数。

dynamic_cast ->如果类型转换失败 返回 NULL

说明: nullptrNULL在C++中都用于表示空指针,那么两者有何区别

  • nullptr 是C++11新引入的 ,nullptr的含义更加明确,它专门用于表示空指针,没有其他的含义,更安全。
  • NULL在C++中通常被定义为整型常量,需要隐式地转换为指针类型。

使用方式: type y = dynamic_cast< 目标类型 >( 源指针 )*

#include<iostream>
#include<string>

using namespace std;

class Test {
public:
	//构造函数
	Test(int age = 12, string name = " 吴献丰 ") {
		age_ = age;
		name_ = name;
	}
	virtual void paly() {
		cout << "一起去玩吗?" << endl;
	}
	//析构函数
	~Test()  { }
protected:
	int age_;
	string name_;
};

class Test2 : public Test {
public:
	Test2(string name) {
		name_ = name;
	}
	void paly() {
		cout << "一起去吃汉堡王吗?" << endl;
	}
	Test2() {  }
private:
	string addr_;
};

int main() {
	Test2 *test2 = new Test2( "重庆秀山" );

	// dynamic_cast  ->如果类型转换失败 返回 NULL
	Test *test = dynamic_cast< Test * > ( test2 );

	if (test == NULL) {
		cout << "类型转换失败: " << endl;
	}else {
		test->paly(); //这里调用的是 派生类的 paly方法->输出一起去吃汉堡王吗?
	}

	return 0;
}

无效的转换 : 基类 -》 派生类

//  Test2  继承至 Test 
Test* test = new Test();
Test2 *test2 = new Test2();

Test2 *t = dynamic_cast< Test2 * > ( test );
Test2* t = dynamic_cast<Test2*>(test);
if (t == NULL) {
	cout << "类型转换失败" << endl;  //程序运行后会输出这句话
}

为什么要使用 dynamic_cast :

1、可以使用基类指针来操作不同类型的对象,而无需知道对象的具体类型。

2、实现基类和派生类的安全转换。如果转换成功,我们可以通过基类的指针来访问派生类的方法。

三、reinterpret_cast 常用于不同类型指针之间的强制转换,甚至是将指针转 换成 整数.

使用方式: type y = reinterpret_cast< type >( expression )

// type-> 需要转换成的目标类型
// expression -> 需要转换的变量或者表达式

Demo : 常见的几种用法

1 、指针之间的转换:例如将int指针转换为char指针。

int x = 10;  
int* int_ptr = &x;  
char* char_ptr = reinterpret_cast<char*>(int_ptr);

2、指针与整数之间的转换:可以指针转换为整数类型,或将整数类型转换为指针。

int x = 10;  
int* int_ptr = &x;  
int int_val = reinterpret_cast<int>(int_ptr);

注意:

  • 这种转换方式没有进行类型检查,因此风险较高。
四、const_cast 主要用于去除对象的常量性限制,或者添加常量性限制

将const对象转换成非const对象 进行修改。

使用方式:

type y = const_cast< type >( expression )

举例说明:

int a = 3;  
const int *b = &a;      // b是一个指向常量的指针,不能通过b修改a的值  
int* c = const_cast<int*>(b); // 使用const_cast去除b的const属性,得到指向非常量的指针c  
*c = 4;                // 通过c修改a的值  
cout << a << *c;        // 输出两个4,表明a的值已经被修改

补充: 对于 const的位置,起到的作用

  • const 加在最前面 : const int *age = &a; // age 所指向的地址的内容不能被改变。

  • const 加在后面: int * const age=&a; // age 的值(也就是它所指向的地址)在初始化后不能再被改变。也就是说age只能指向a。

  • const 加在前后 : const int * const age = &a; //age 所指向的地址的内容不能被改变 , 同时 age 只能指向a, 指向其他变量的地址会报错。也就是说 age 的值和它所指向的地址的内容都不能被改变。

注意:

1、const_cast不能用于修改变量本身的const属性,只能修改指针或引用的const属性,再通过间接修改的方式来改变变量的值
在这里插入图片描述


2、常量字符串不能去 const 修改。编译通过了,但是程序运行时之间崩了。

在这里插入图片描述

3、在去常量限定符之间,要保证指针所指向的内存能够修改,不能修改会引起异常。
4、仅针对指针和引用。

类型转换使用总结:

1、static_cast 静态·类型·转换,编译时C++编译器会对类型进行检查,所以能隐射类型转换的,就用static_cast.

2、dynamic_cast<>() 动态类型转换,安全的虚基类和子类之间转换,运行时也会进行类型检查。

3、const_cast<>() 去除变量的只读属性。

4、不同类型之间进行强制类型转换,用reinterpret_cas<>()进行重新解释。

5、static_cast <>()和reinterpret_cas<>(),基本上把c语言中的 强制类型转换给覆盖了。值得注意的是reinterpret_cas<>()很难保证移植性。

C++大牛建议: 一般情况下,不建议进行类型转换,避免进行类型转换。

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/1114088.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

Linux系统编程:进程part_1

进程 进程以概念为主&#xff0c;知道是怎么回事就行&#xff0c;工作一般都操作线程。 进程的基本概念 因为这些概念在OS教课书中讲的太多&#xff0c;故而这一块不会详述。 什么是进程&#xff1f; 通俗的说进程就是正在运行的程序。进程是动态的程序是静态的。 使用cat…

Pytest测试框架搭建的关键6个知识点(建议收藏)

在现代软件开发中&#xff0c;测试是确保代码质量和功能稳定性的关键步骤。而Pytest作为一个功能强大且易于使用的Python测试框架&#xff0c;为我们提供了一个优雅的方式来编写和管理测试。本文将为你介绍如何构建高效可靠的测试环境&#xff0c;着重探讨Pytest测试框架搭建时…

基于SSM的二手商品交易系统

基于SSM的二手商品交易系统 开发语言&#xff1a;Java数据库&#xff1a;MySQL技术&#xff1a;SpringSpringMVCMyBatisVue工具&#xff1a;IDEA/Ecilpse、Navicat、Maven 系统展示 首页 商品详情 登录界面 管理员界面 商品管理 摘要 基于Spring&#xff08;Spring MVC&…

mysql第一篇---索引

文章目录 mysql第一篇---索引索引的数据结构为什么使用索引&#xff1f;索引的及其优缺点InnoDB中索引的推演常见的索引概念InnoDB的B树索引的注意事项MyISAM中索引方案索引的代价MySQL数据结构选择的合理性 mysql第一篇—索引 索引的数据结构 为什么使用索引&#xff1f; 索…

Git快速安装【附安装包资源】

软件安装包 项目版本管理软件 Git windows版本安装包 安装步骤 双击按照包之后&#xff0c;直接next 安装位置尽量不要选择C盘&#xff0c;如果只有C盘&#xff0c;可以尝试分盘&#xff0c;如果C盘已经很小了&#xff0c;那就没办法了 选择完安装位置之后&#xff0c;直…

班主任好物 班级查询系统来啦

哈喽各位&#xff0c;作为一名教育博主&#xff0c;今天我要给大家分享一个班主任的好物——班级查询系统&#xff01;这个系统可真是太方便了呢&#xff0c;那么&#xff0c;这个神秘的班级查询系统到底是什么呢&#xff1f;别急&#xff0c;听我慢慢道来。 班级查询系统&…

数据分析:小红书节点投放指南,引爆双十一!

导语 双11大促将临&#xff0c;对于多数品牌方而言&#xff0c;其中蕴藏着巨大的流量增长机遇。面对竞争激烈的小红书种草平台&#xff0c;品牌方们又该如何提前做好准备&#xff0c;掌握营销节奏&#xff0c;真正抓住流量密码呢&#xff1f;接下来由小编一一道来。 双十一剁…

前端 js 之 面向对象(原型、原型链及继承) 06

今天又是一个美好的一天耶 &#xff01; ✌ 文章目录 一、面向对象编程之前二、原型 与 原型链 &#x1f381;三、new 的原理 &#x1f91e;四、面向对象的优势五、继承 (构造函数之间的)ps&#xff1a; 一、面向对象编程之前 在面向对象编程之前&#xff0c;我们是 面向二进制…

Jmeter(五):json提取器元件及jsonpath介绍,响应断言元件

Jmeter&#xff1a;son提取器元件及jsonpath介绍 json提取器元件介绍 json提取器与正则表达式提取器功能类似&#xff0c;也是用来截取响应信息的部分保 存到指定的变量中去&#xff0c;不同的是&#xff0c;它只能用来处理响应正文&#xff0c;并且响应正文必须 是json格式的…

分享一下微信小程序开发的步骤是什么

随着微信小程序的日益普及和深入人心&#xff0c;许多企业和开发者都开始投身于小程序开发领域。那么&#xff0c;如何从零开始&#xff0c;一步步开发出一个自己的微信小程序呢&#xff1f;下面就让我们一起探讨微信小程序开发的步骤。 一、确定开发目标和定位 在开始开发小程…

Cesium Vue(六)— 材质(Material)

1. 设置entity材质 添加棋盘纹理材质 // 棋盘纹理 let material new Cesium.CheckerboardMaterialProperty({ evenColor: Cesium.Color.RED, oddColor: Cesium.Color.YELLOW, repeat: new Cesium.Cartesian2(2, 2), });添加条纹纹理材质 // 条纹纹理 let material new Cesium…

蓝牙5.4的几个新特性

前述文章《蓝牙5.4引入PAwR&#xff0c;电子价签迎来新机遇》中我们介绍了蓝牙5.4的PAwR特性&#xff0c;该特性的引入使得电子价签领域迎来了新的机遇&#xff0c;但其实蓝牙5.4一共引入了4个特性&#xff0c;本文将逐一进行介绍后面3个特性。 首先来回顾一下蓝牙5.4的几个新…

安装Sentinel

大家好今天来安装Sentinel . 安装Sentinel 下载 : 大家可以选择相应版本(最新版本1.8.6) 官网下载地址 : Release v1.8.6 alibaba/Sentinel GitHub 链接&#xff1a;Sentinel_免费高速下载|百度网盘-分享无限制 (baidu.com) 提取码&#xff1a;8eh9 运行 : 将jar包放到任…

4957B/D/E/F射频/微波综合测试仪

4957B/D/E/F 射频微波综合测试仪 频率范围&#xff1a;30k~40GHz ​4957B/D/E/F射频/微波综合测试仪频率范围可达6.5GHz/18GHz/26.5GHz/40GHz&#xff0c;集双端口矢量网络分析、电缆和天馈线测试、矢量电压测量、频谱分析&#xff08;通道功率、邻道功率、占用带宽、干扰分…

认识web自动化测试!

1.什么是自动化测试&#xff1f; 自动化测试的概念: 软件自动化测试就是通过测试工具或者其他手段&#xff0c;按照测试人员的预定计划对软件产品进行自动化测试&#xff0c;他是软件测试的一个重要组成部分&#xff0c;能够完成许多手工测试无法完成或者难以实现的测试工作&a…

2023年天猫双十一预售下定金抢红包玩法介绍

2023年天猫双十一预售下定金抢红包玩法介绍 2023年双11预售期间&#xff0c;用户可下定金抢红包。红包可用于抵扣商品货款金额&#xff0c;但有使用规则&#xff1a;红包需在有效期内使用&#xff0c;逾期作废;不同商品可使用的红包有优先级。不同场景下的红包使用要求不同&…

无人机遥控中应用的2.4GHz无线芯片

无人驾驶飞机简称“无人机”&#xff0c;英文缩写为“UAV”&#xff0c;是利用无线电遥控设备和自备的程序控制装置操纵的不载人飞机&#xff0c;或者由车载计算机完全地或间歇地自主地操作。是一种不需要人操控就能够自主飞行的飞行器&#xff0c;它可以执行多种任务&#xff…

亲测好用教师小程序

作为一名老师&#xff0c;经常需要面对的一大挑战就是如何有效地向学生和家长传达重要的学业信息。而其中&#xff0c;成绩的发布与查询更是重中之重。传统的做法是手动录入数据&#xff0c;或者通过电子邮件发送Excel表格&#xff0c;这样做既繁琐又耗时。幸运的是&#xff0c…

ETX很小

windows桌面调节分辨率即可&#xff1a;

Windows Defender防火墙配置错误与GPO:梳理关键点

许多企业在网络中拥有不同的组成部分&#xff0c;包括Windows Defender防火墙、GPO和AD基础设施。网络中的任何部分都可能存在漏洞&#xff0c;这些漏洞可能引发多米诺效应。一旦第一个多米诺出现问题&#xff0c;整个链条都会受到牵连&#xff0c;可能会对您的网络造成无法挽回…