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的值改为6k = 6;//j 和 k的值一致。printf("j = %d,k = %d\n", j, k);//将x的变量改成8y = 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_castc = reinterpret_cast<char>(i);return 0;
}

在这里插入图片描述

dynamic_cast

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

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

小结:

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

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

如若内容造成侵权/违法违规/事实不符,请联系编程知识网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

本地化小程序运营 同城小程序开发

时空的限制让本地化的线上平台成为一种追求&#xff0c;58及某团正式深挖人们城镇化、本地化的信息和商业需求而崛起的平台&#xff0c;将二者结合成本地化小程序&#xff0c;显然有着巨大的市场机会。本地化小程序运营可以结合本地化生活需求的一些信息&#xff0c;以及激发商…

pid调参(实验室新人入门)

安装keil&#xff1a;下载MDK-ARM http://t.csdnimg.cn/yYF7W芯片包&#xff1a; https://www.keil.arm.com/devices/stmicroelectronics-stm32f429aghx/features/ 调参软件&#xff1a; https://blog.csdn.net/weixin_63568691/article/details/133606043调参方法&#xff1a;…

解决Mac配置maven环境后,关闭终端后环境失效的问题(适用于所有终端关闭后环境失效的问题)

目录 问题的原因 解决方式一、每次打开终端时输入&#xff1a;"source ~/.bash_profile"&#xff0c;这个方式比较繁琐 解决方式二、我们终端输入"vim ~/.zshrc"打开".zshrc"文件 1、我们输入以下代码&#xff1a; 2、首先需要按 " i…

字符设备驱动基础框架

一、总体框架 1.Linux字符设备驱动工作原理图 2.驱动使用端 3.驱动实现端 二、各部分详解 1.VFS层 1) inode结构体 在Unix/Linux操作系统中&#xff0c;每个文件都由一个inode&#xff08;索引节点&#xff09;来索引。inode是特殊的磁盘块&#xff0c;它们在文件系统创建时…

20.有效的括号(LeetCode)

思路&#xff1a;用栈的后进先出的特性&#xff0c;来完成题目的要求 因为C有库&#xff0c;可以直接用&#xff0c;而C语言没有&#xff0c;所以我们直接把写好的栈拷贝上来用。 首先&#xff0c;完成框架的搭建 其次&#xff0c;再实现循环内的部分。1.左括号入栈 2.右括…

安装 Lua 的 HTTP 库

首先&#xff0c;你需要安装 Lua 的 HTTP 库。可以使用 LuaRocks 来安装。以下是安装命令&#xff1a; luarocks install http然后&#xff0c;你可以使用以下代码来爬取网页内容&#xff1a; local http require http-- 设置代理信息 http.set_proxy(jshk.com.cn)-- 网页UR…

【解决】conda-script.py: error: argument COMMAND: invalid choice: ‘activate‘

运行conda activate base报错&#xff1a; 试了网上找到的解决方法都不行&#xff1a; 最后切换了一下terminal&#xff1a; 从powershell改回cmd&#xff08;不知道为什么一开始手贱换成powershell&#xff09; 就可以了

手机厂商参与“百模大战”,vivo发布蓝心大模型

在2023 vivo开发者大会上&#xff0c;vivo发布自研通用大模型矩阵——蓝心大模型&#xff0c;其中包含十亿、百亿、千亿三个参数量级的5款自研大模型&#xff0c;其中&#xff0c;10亿量级模型是主要面向端侧场景打造的专业文本大模型&#xff0c;具备本地化的文本总结、摘要等…

高频SQL50题(基础题)-5

文章目录 主要内容一.SQL练习题1.602-好友申请&#xff1a;谁有最多的好友代码如下&#xff08;示例&#xff09;: 2.585-2016年的投资代码如下&#xff08;示例&#xff09;: 3.185-部门工资前三高的所有员工代码如下&#xff08;示例&#xff09;: 4.1667-修复表中的名字代码…

Android图形系统之X11、Weston、Wayland、Mesa3D、ANGLE、SwiftShader介绍(十五)

简介&#xff1a; CSDN博客专家&#xff0c;专注Android/Linux系统&#xff0c;分享多mic语音方案、音视频、编解码等技术&#xff0c;与大家一起成长&#xff01; 优质专栏&#xff1a;Audio工程师进阶系列【原创干货持续更新中……】&#x1f680; 人生格言&#xff1a; 人生…

【PG】PostgreSQL 预写日志(WAL)、checkpoint、LSN

目录 预写式日志&#xff08;WAL&#xff09; WAL概念 WAL的作用 WAL日志存放路径 WAL日志文件数量 WAL日志文件存储形式 WAL日志文件命名 WAL内容 检查点&#xff08;checkpoint&#xff09; 1 检查点概念 2 检查点作用 触发检查点 触发检查点之后数据库操作 设置合…

JVM如何运行,揭秘Java虚拟机运行时数据区

目录 一、概述 二、程序计数器 三、虚拟机栈 四、本地方法栈 五、本地方法接口 六、堆 &#xff08;一&#xff09;概述 &#xff08;二&#xff09;堆空间细分 七、方法区 一、概述 不同的JVM对于内存的划分方式和管理机制存在部分差异&#xff0c;后续针对HotSpot虚…