5 新的关键字

动态内存分配

回想C语言中,动态内存是怎么分配的?通过C库里面的malloc free去进行动态内存分配。
C++通过new关键字进行动态内存申请,动态内存申请是基于类型进行的。
delete 关键字用于内存释放。

//变量申请
type* pointer = new type;
delete pointer;

//数组申请
type* pointer = new tyep[10];
delete[] pointer;
//数组释放一定要加 []
int *p = new int[10];
//.......
delete p;//会造成内存泄漏。这句话的意思是告诉编译器只释放p指向的一个int型空间,而不是所有的数组空间。
delete [] p;//正确的写法

new关键字与malloc函数的区别

  • new关键字是c++的一部分,malloc是由c库提供的函数。
  • new以具体类型为单位进行内存分配,而malloc只能以字节为单位进行内存分配。
  • new在申请单个类型变量时可进行初始化,malloc不具备内存初始化的特性。
#include <stdio.h>

int main()
{
    int* a = new int(6);
    float* b = new float(7.0);
    char* c = new char('c');
    printf("*a = %d, *b = %f, *c = %c\n", *a, *b, *c);
    delete a;
    delete b;
    delete c;
    return 0;
}

C++中命名空间

在C语言中,只有一个全局作用域。C语言中所有的全局标识符共享同一个作用域,那么项目很大时,标识符之间就有可能发生冲突。
C++中提出了命名空间的概念。目的是将全局作用域划分为不同的块。
命名空间定义:
namespace name { //}

#include <stdio.h>
namespace First
{
	int i = 0;
}
namespace Second
{
    int i = 1;
	namespace Internal
	{
		struct P
		{
			int x;
			int y;
		};
	}
}

int main()
{
    return 0;
}

命名空间的使用

使用整个命名空间: using namespace name;
使用命名空间中的变量:using name::variable
使用默认命名空间中的变量:::variable
默认情况下,可以直接使用默认命名空间中所有的标识符。

#include <stdio.h>
namespace First
{
	int i = 0;
}
namespace Second
{
    int i = 1;
	namespace Internal
	{
		struct P
		{
			int x;
			int y;
		};
	}
}

int main()
{
	using namespace First;//告诉编译器,解开First域
	using Second::Internal::P;//告诉编译器要用Second空间中Internal空间中的P成员变量。
	printf("i = %d\n", i);//打印0,使用的是First 空间中的i。因为我们没有解开Second 空间
	printf("i = %d\n", Second::i);//打印1,告诉编译器访问的是Second 空间中的i。
	P p = {2, 3};
	printf("p.x=%d, p.y=%d\n", p.x, p.y);
    return 0;
}

在这里插入图片描述

强制类型转换

C方式的强制类型转换(type)(expression) or type(expression)

#include <stdio.h>
//定义一个函数指针
typedef void(PF)(int);

struct Point
{
	int x;
	int y;
};

int main()
{
    int v = 0x12345;
	//将变量v强制类型转换为函数指针
	PF* pf = (PF*)v;
	//将变量v强制类型转换为char型
	char c = char(v);
	//调用v变量强制转换为函数的地址函数,此处不一定是函数。
	pf(v);
	//将v变量强制转换为结构体指针。
	Point* p = (Point*) v;
	printf("p->x = %d\n", p->x);
	printf("p->y = %d\n", p->y);
}

在这里插入图片描述

C强制类型转换过于粗暴,任意类型之间都可以进行转换,编译器很难判断其正确性;且在源码中无法快速定位所有使用强制类型转换的语句,出现问题时难以定位。
在现代软件工程中,最难定位问题的三种问题:
1.强制类型转换。
2.多线程的交互。
3.位运算优先级,数学运算、逻辑运算混在一起。
在程序设计理论中,强制类型转换也是不被推荐的,与goto语句一样,尽量避免。
C++提供了更安全的强制类型转换。将强制类型转换分为4中不同的类型。static_cast const_cast dynamic_cast reinterpret_cast 。用法xxx_cast<type>(expression)

static_cast

  • 用于基本类型间的转换,但不能用于基本类型指针间的转换
  • 用于有继承关系类对象之间的转换和类指针之间的转换。
#include <stdio.h>

int main()
{
    int i = 8;
	char c = 'B';
	int* pi = &i;
	char * pc = &c;
	
	c = static_cast<char>(i);
    pc = static_cast<char*>(pi);	
    return 0;
}

在这里插入图片描述
static_cast是编译期进行转换的,无法在运行时检测类型。所以类类型之间的转换可能存在风险。

const_cast

  • 用于去除变量的const属性
#include <stdio.h>

int main()
{
	//const 引用j,初始化的时候j就是一个只读变量。
	//注意第二节讲到 const引用只有定义的别名拥有只读属性,不会影响到正名
    const int& j = 1;
	//将只读变量j的const属性去掉,j就降级为普通变量。
	int& k = const_cast<int&>(j);
	//声明一个真正的常量x。
	const int x = 2;
	//由于对x常量取引用,前面学习了,引用本身就是地址别名,是指针。
	//所以此处编译器会为这个常量分配一个空间。
	//y就指向了常量x的地址,y就变成了普通变量。
	int& y = const_cast<int&>(x);
	//将j的值改为6
	k = 6;
	//j 和 k的值一致。
	printf("j = %d,k = %d\n", j, k);
	//将x的变量改成8
	y = 8;
	//所以x 和 y的地址一样的。
	//const引用只有定义的别名拥有只读属性,不会影响到正名,所以x的值还是2,因为是常量,编译器直接替换。
	printf("x = %d, y = %d\n", x, y);
	printf("&x = %p, &y = %p\n", &x, &y);
	return 0;
}

在这里插入图片描述
上面程序中运用到了第二节的知识点:const 常量只有定义的别名拥有只读属性,不会影响到正名。
int& y = const_cast<int&>(x);在解除const属性时,会为x分配内存空间,此时引用y指向这段编译器为x分配的空间,引用y就是普通变量。但是x还是常量,编译器依然认为其不能被赋值。假如下面有一段语句x=8;则编译器还是会报错。

reinterpret_cast

  • 用于指针类型间的强制类型转换
  • 用于整数和指针类型间的强制转换
    reinterpret_cast直接从二进制位进行复制,是一种及其不安全的转换。
#include <stdio.h>

typedef void (PF)(int);

int main()
{
	int i = 0;
	char c = 'C';
	//将字符变量c的地址强制转换为int型指针,并且赋值给pi指针。
	int* pi = reinterpret_cast<int*>(&c);
	//将int变量i的地址强制转换为char型指针,并赋值给pc指针。
	char* pc = reinterpret_cast<char*>(&i);
	//将0x888888地址,强制转换为PF型函数指针,并赋值给pf指针。
	PF* pf = reinterpret_cast<PF*>(0x888888);
	//将int类型变量转换为char,不是用reinterpret_cast,而是static_cast
	c = reinterpret_cast<char>(i);
	return 0;
}

在这里插入图片描述

dynamic_cast

  • 主要用于类层次间的转换,还可以用于类之间的交叉转换
  • 具有运行时类型检查的功能,比static_cast更安全

类是什么?对象是什么?类层次是什么?

小结:

  • C++中内置了动态内存分配的专用关键字
  • C++中的动态内存分配是基于类型进行的,C的malloc函数是基于字节为单位分配。
  • C++中命名空间的概念用于解决符号名相同的冲突问题。
  • C++细化了C语言中强制类型转换方式。C++不推荐在程序中使用强制类型转换;建议在强制类型转换时考虑一下究竟希望什么样的转换。

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

如若内容造成侵权/违法违规/事实不符,请联系我们进行投诉反馈qq邮箱809451989@qq.com,一经查实,立即删除!

相关文章

arcgis提取栅格有效边界

方法一&#xff1a;【3D Analyst工具】-【转换】-【由栅格转出】-【栅格范围】 打开一幅栅格数据&#xff0c;利用【栅格范围】工具提取其有效边界&#xff08;不包含NoData值&#xff09;&#xff1a; 方法二&#xff1a;先利用【栅格计算器】将有效值赋值为1&#xff0c;得到…

【CCF BDCI 2023】多模态多方对话场景下的发言人识别 Baseline

模型简介 本基线模型共分为三个部分&#xff1a; 基于CNN的判断每张人脸是否是说话人的模型&#xff1b;基于Transformer-Encoder的判断同一段对话中不同轮次的说话人关系的模型&#xff1b;和使用上述两个预测结果求解二次型优化问题的说话人识别求解器。 基于CNN的判断每…

VSCode 好用的插件分享

文章目录 Introlistcode runner 【在文本编辑器中编辑好各类语言的源代码&#xff0c;然后一键运行】gitlens - 【git提交信息即时查看&#xff0c;类似IDEA中的 show annotation】还有更多&#xff0c;会日常补充。 Intro 大四毕业前&#xff0c;我只有一台dell latitude 455…

瑞萨e2studio(29)----SPI速率解析

瑞萨e2studio.29--SPI速率解析 概述视频教学时钟配置解析RA4M2的BRR值时钟速率7.5M下寄存器值3K下寄存器值 概述 在嵌入式系统的设计中&#xff0c;串行外设接口&#xff08;SPI&#xff09;的通信速率是一个关键参数&#xff0c;它直接影响到系统的性能和稳定性。瑞萨电子的…

No200.精选前端面试题,享受每天的挑战和学习

🤍 前端开发工程师(主业)、技术博主(副业)、已过CET6 🍨 阿珊和她的猫_CSDN个人主页 🕠 牛客高级专题作者、在牛客打造高质量专栏《前端面试必备》 🍚 蓝桥云课签约作者、已在蓝桥云课上架的前后端实战课程《Vue.js 和 Egg.js 开发企业级健康管理项目》、《带你从入…

【Android】画面卡顿优化列表流畅度四之Glide几个常用参数设置

好像是一年前快两年了&#xff0c;笔者解析过glide的源码&#xff0c;也是因为觉得自己熟悉一些&#xff0c;也就没太关注过项目里glide的具体使用对当前业务的影响&#xff1b;主要是自负&#xff0c;还有就是真没有碰到过这样的数据加载情况。暴露了经验还是不太足够 有兴趣的…

点大商城V2版 2.5.3全插件开源独立版 百度+支付宝+QQ+头条+小程序端+unipp开源端安装测试教程

点大商城V2是一款采用全新界面设计支持多端覆盖的小程序应用&#xff0c;支持H5、微信公众号、微信小程序、头条小程序、支付宝小程序、百度小程序&#xff0c;本程序是点大商城V2独立版&#xff0c;包含全部插件&#xff0c;代码全开源&#xff0c;并且有VUE全端代码。 适用范…

Java17新增特性

前言 前面的文章&#xff0c;我们对Java9、Java10、Java11、Java12 、Java13、Java14、Java15、Java16 的特性进行了介绍&#xff0c;对应的文章如下 Java9新增特性 Java10新增特性 Java11新增特性 Java12新增特性 Java13新增特性 Java14新增特性 Java15新增特性 Java16新增特…

Matlab论文插图绘制模板第126期—分组三维气泡图

在之前的文章中&#xff0c;分享了Matlab三维气泡图的绘制模板&#xff1a; 特征渲染的三维气泡图&#xff1a; 进一步&#xff0c;再来分享一下分组三维气泡图。 先来看一下成品效果&#xff1a; 特别提示&#xff1a;本期内容『数据代码』已上传资源群中&#xff0c;加群的朋…

手机能做静态二维码吗?用手机做二维码的教程

现在手机上有很多的功能&#xff0c;能够帮助我们应对日常生活中的各种问题&#xff0c;那么如果我们想要在手机上生成一个静态二维码&#xff0c;大家知道该怎么来操作吗&#xff1f;一般制作二维码需要专业的二维码生成工具才可以完成制作&#xff0c;那么下面小编来给大家分…

RabbitMQ-基础篇-黑马程序员

代码&#xff1a; 链接&#xff1a; https://pan.baidu.com/s/1nQBIgB_SbzoKu_XMWZ3JoA?pwdaeoe 提取码&#xff1a;aeoe 微服务一旦拆分&#xff0c;必然涉及到服务之间的相互调用&#xff0c;目前我们服务之间调用采用的都是基于OpenFeign的调用。这种调用中&#xff0c;调…

2023年亚太杯数学建模思路 - 案例:FPTree-频繁模式树算法

文章目录 赛题思路算法介绍FP树表示法构建FP树实现代码 建模资料 赛题思路 &#xff08;赛题出来以后第一时间在CSDN分享&#xff09; https://blog.csdn.net/dc_sinor?typeblog 算法介绍 FP-Tree算法全称是FrequentPattern Tree算法&#xff0c;就是频繁模式树算法&#…

Maya v2024(3D动画制作软件)

Maya 2024是一款三维计算机图形动画制作软件。它被广泛应用于电影、电视、游戏、动画等领域中&#xff0c;用于创建各种三维模型、场景、特效和动画。 以下是Maya的主要特点&#xff1a; 强大的建模工具&#xff1a;Maya提供了各种建模工具&#xff0c;如多边形建模、NURBS建模…

lamp环境搭建(kali,docker,ubuntu)

学了微专业,然后第一节课是学的搭建自己的环境,这里记录一下吧。 搭建一个lamp环境 (因为本人使用的是kali而且还带有集成环境的xampp,本身就自带了apache2,mysql和php。)后面有用ubuntu从0开始搭建的。 在kali环境下: 1.首先查看apache2和mysql和php 查看apache2 where…

Python中的数据增强技术

使用imgaug快速观察Python中的数据增强技术 在本文中&#xff0c;我们将使用imgaug库来探索Python中不同的数据增强技术 什么是图像增强 图像增强是一种强大的技术&#xff0c;用于在现有图像中人为地创建变化以扩展图像数据集。这是通过应用不同的变换技术来实现的&#xf…

矩阵置零00

题目链接 矩阵置零 题目描述 注意点 使用 原地 算法 解答思路 思路是需要存储每一行以及每一列是否有0&#xff0c;因为要尽可能使用更少的空间&#xff0c;且新设置为0的格子不能对后续的判断产生影响&#xff0c;所以要在原有矩阵上存储该信息先用两个参数存储第一行和第…

飞天使-django创建一个初始项目过程

创建django项目 运行项目 运行命令 pyhont manage.py runserver 然后访问 http://127.0.0.1:8000/&#xff0c; 则可以打开本地新建的项目 虚拟环境的部署-mac 在一台计算机上可以通过虚拟环境实现多个版本Django的开发环境 安装虚拟环境工具&#xff1a;如果你的系统中没有安…

properties文件乱码

出现如下乱码&#xff1a; 按照步骤修改编码方式就可以解决啦 修改之后结果就是下面这样~

搜索引擎项目

认识搜索引擎 1、有一个主页、有搜索框。在搜索框中输入的内容 称为“查询词” 2、还有搜索结果页&#xff0c;包含了若干条搜索结果 3、针对每一个搜索结果&#xff0c;都会包含查询词或者查询词的一部分或者和查询词具有一定的相关性 4、每个搜索结果包含好几个部分&…

微软允许OEM对Win10不提供关闭Secure Boot

用户可能将无法在Windows 10电脑上安装其它操作系统了&#xff0c;微软不再要求OEM在UEFI 中提供的“关闭 Secure Boot”的选项。 微软最早是在Designed for Windows 8认证时要求OEM的产品必须支持UEFI Secure Boot。Secure Boot 被设计用来防止恶意程序悄悄潜入到引导进程。问…