5 新的关键字

news2024/12/22 18:39:50

动态内存分配

回想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++不推荐在程序中使用强制类型转换;建议在强制类型转换时考虑一下究竟希望什么样的转换。

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

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

相关文章

TDengine 与煤科院五大系统实现兼容性互认,助力煤矿智能化安全体系搭建

近日&#xff0c;涛思数据与煤炭科学技术研究院&#xff08;以下简称煤科院&#xff09;已完成数个产品兼容互认证工作&#xff0c;经双方共同严格测试&#xff0c;涛思数据旗下物联网、工业大数据平台 TDengine V3.X 与煤炭科学技术研究院旗下煤矿复合灾害监测监控预警系统、煤…

css渐变背景,linear-gradient()线性渐变和radial-gradient()径向渐变

嗨&#xff0c;大家好&#xff0c;我是爱搞知识的咸虾米。 许多APP、小程序、网站等都喜欢采用渐变色背景&#xff0c;这样做不但可以增加设计感&#xff0c;而且能提升品牌辨识度。 所以&#xff0c;今天使用css的线性渐变和径向渐变&#xff0c;给大家将这几种不同类型的渐变…

web 服务

作业&#xff1a;请给openlab搭建web网站 网站需求&#xff1a; 1.基于域名 www.openlab.com 可以访问网站内容为 welcome to openlab!!! 2.给该公司创建三个子界面分别显示学生信息&#xff0c;教学资料和缴费网站&#xff0c; 1、基于 www.openlab.com/student 网站访问学生信…

适配器模式 rust和java的实现

文章目录 适配器模式介绍何时使用应用实例优点缺点使用场景 实现java实现rust 实现 rust代码仓库 适配器模式 适配器模式&#xff08;Adapter Pattern&#xff09;是作为两个不兼容的接口之间的桥梁。这种类型的设计模式属于结构型模式&#xff0c;它结合了两个独立接口的功能…

时序数据库 TDengine + 高级分析软件 Seeq,助力企业挖掘时序数据潜力

作为一款制造业和工业互联网&#xff08;IIOT&#xff09;高级分析软件&#xff0c;Seeq 支持在工艺制造组织中使用机器学习创新的新功能。这些功能使组织能够将自己或第三方机器学习算法部署到前线流程工程师和主题专家使用的高级分析应用程序&#xff0c;从而使单个数据科学家…

腾讯云5年云服务器还有吗?腾讯云5年时长服务器入口在哪?

如果你是一名企业家或者是一个热衷于数字化转型的创业者&#xff0c;那么腾讯云最近推出的一项优惠活动绝对不会让你无动于衷。现在&#xff0c;腾讯云正在大力推广一项5年特价云服务器活动&#xff0c;只需要花费3879元&#xff0c;你就可以享受到腾讯云提供的优质服务。 腾讯…

如何保护电动汽车充电站免受网络攻击

根据国际能源署 (IEA) 的一份报告&#xff0c;如今&#xff0c;全球销售的汽车中约有七分之一是电动汽车。虽然这对环境来说是个好消息——有可能使占总碳排放量16% 的道路交通脱碳——但这也带来了针对电动汽车充电站的网络攻击日益严重的威胁。 电动汽车充电站、数据流网络和…

Python中的数据增强技术

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

在 SQL 中,当复合主键成为外键时应该如何被其它表引用

文章目录 当研究一个问题慢慢深入时&#xff0c;一个看起来简单的问题也暗藏玄机。在 SQL 中&#xff0c;主键成为外键这是一个很平常的问题&#xff0c;乍一看没啥值得注意的。但如果这个主键是一种复合主键&#xff0c;而另一个表又引用这个键作为它的复合主键&#xff0c;问…

Android R.fraction

来源 我是在看Android10原生代码&#xff0c;绘制状态栏蓝牙电量相关类中第一次看到R.fraction的&#xff0c;如类BatteryMeterDrawable <fraction name"battery_button_height_fraction">10%</fraction> mButtonHeightFraction context.getResources(…

Jenkins入门——安装docker版的Jenkins 配置mvn,jdk等 使用案例初步 遇到的问题及解决

前言 Jenkins是开源CI&CD软件领导者&#xff0c; 提供超过1000个插件来支持构建、部署、自动化&#xff0c; 满足任何项目的需要。 官网&#xff1a;https://www.jenkins.io/zh/ 本篇博客介绍docker版的jenkins的安装和使用&#xff0c;maven、jdk&#xff0c;汉语的配置…

Oracle数据库、实例、用户、表空间和表之间的关系

一、Oracle数据库中数据库、实例、用户、表空间和表&#xff08;索引、视图、存储过程、函数、对象等对象&#xff09;之间的关系。 1、Oracle的数据库是由一些物理文件组成&#xff1a;数据文件控制文件重做日志文件归档日志文件参数文件报警和跟踪日志文件备份文件。 2、实…

2023.11.11通过html内置“required-star“添加一个红色的星号来表示必填项

2023.11.11通过html内置"required-star"添加一个红色的星号来表示必填项 在HTML中&#xff0c;可以使用标签来为元素添加说明。同时可以通过添加一个红色的星号来表示必填项。 <!DOCTYPE html> <html lang"en"> <head><meta charse…

Java整合Redis实现坐标附近查询

目录 一、GEO用法引入 二、引入依赖 三、实体类 四、添加位置信息 五、查询位置信息 一、GEO用法引入 GEO&#xff0c;全称Geolocation&#xff0c;代表地理坐标。可以在其中存储地理坐标信息&#xff0c;帮助我们根据经纬度来检索数据。常见的命令有&#xff1a;GEOADD&…

东莞松山湖数据中心|莞服务器托管的优势

东莞位于珠江三角洲经济圈&#xff0c;交通便利&#xff0c;与广州、深圳等大城市相邻&#xff0c;而且东莞是中国重要的制造业基地&#xff0c;有众多的制造业和科技企业集聚于此&#xff0c;随着互联网和数字化时代的到来&#xff0c;企业都向数字化转型&#xff0c;对于信息…

CSS特效009:音频波纹加载律动

总第 009 篇文章&#xff0c; 查看专栏目录 本专栏记录的是经常使用的CSS示例与技巧&#xff0c;主要包含CSS布局&#xff0c;CSS特效&#xff0c;CSS花边信息三部分内容。其中CSS布局主要是列出一些常用的CSS布局信息点&#xff0c;CSS特效主要是一些动画示例&#xff0c;CSS花…

Docker安装详细步骤及相关环境安装配置(mysql、jdk、redis、自己的私有仓库Gitlab 、C和C++环境以及Nginx服务代理)

目录 一、从空白系统中克隆Centos7系统 二、使用xshell连接docker_tigerhhzz虚拟机​编辑 三、在CentOS7基础上安装Docker容器 四、在Docker中进行安装Portainer 4.1、在Docker中安装MySQL 4.2、在Docker中安装JDK8&#xff0c;安装Java环境 4.3、Docker安装redis&#…

华为笔记本电脑原装win10/win11系统恢复安装教程方法

华为电脑matebook 14原装Win11系统带F10智能还原 安装恢复教程&#xff1a; 1.安装方法有两种&#xff0c;一种是用PE安装&#xff0c;一种是华为工厂包安装&#xff08;安装完成自带F10智能还原&#xff09; 若没有原装系统文件&#xff0c;请在这里获取&#xff1a;https:…

RabbitMQ传统数据持久化和Lazy queue的区别

问题引出&#xff1a; 在了解这个问题前我们需要一些前置知识&#xff1a; 关于MQ可靠性&#xff0c;在默认情况下&#xff0c;RabbitMQ会将接收到的信息保存在内存中以降低消息收发的延迟。这样会导致两个问题&#xff1a; 一旦MQ宕机&#xff0c;内存中的信息会丢失 内存空…

list复制出新的list后修改元素,也更改了旧的list?

例子 addAll() Testpublic void CopyListTest(){Student student Student.builder().id(1).name("张三").age(23).classId(1).build();Student student2 Student.builder().id(2).name("李四").age(22).classId(1).build();List<Student> student…