C++深度解析 C++中的新成员---new,delete,命名空间namespace(9)
参考:【C++ Primer Plus(第六版)4.7 指针和自由存储空间 4.8 指针、数组和指针算术】
C++动态内存分配
关键字new: 进行动态内存分配申请(基于类型进行的)
关键字delete:用于内存释放
变量的申请:
Type* pointer = new Type; //从堆空间申请Type类型的变量
// ......
delete pointer; //释放指针所指向那个元素的动态内存空间
数组的申请:
Type* pointer = new Type[N];
// ......
delete[] pointer; //将整个数组空间释放
示例程序:(动态内存分配)
#include <stdio.h>
int main()
{
//定义一个指针,指向一个int类型的变量
//并且向堆空间里面申请一个int类型变量,将p指向该内存地址
//p指向4个字节的堆空间
int *p = new int;
*p = 5;
*p = *p + 10;
printf("p = %p\n", p);
printf("*p = %d\n", *p); //15
//释放p所指向的堆空间
delete p;
//将指针变量p指向一片内存空间(数组)
//p所指向的数组空间至少占用40字节!!(动态申请的内存空间可能比实际大一点!!)
p = new int[10];
for (int i = 0; i < 10; i++)
{
p[i] = i + 1;
printf("p[%d] = %d\n", i, p[i]);
}
delete[] p;
return 0;
}
结果如下:
注意:代码 p = new int[10];,p所指向的数组空间占用至少40个字节,因为C++兼容C语言的特性,所以动态申请的空间也许比实际大一点。
C++的new关键字 与 C语言的malloc库函数的区别
new关键字:是C++的一部分,以具体类型(例:int,float)为单位进行内存分配,在申请单个类型变量时可进行初始化。
malloc函数:是由C库提供的函数,以字节为单位进行内存分配,不具备内存初始化的特性。
new关键字的初始化
//指针pi指向堆空间int类型变量,申请的同时将int初始化为1
int* pi = new int(1);
//pf指向float类型变量指针,pf指针指向堆空间float变量,申请完后立即初始化为2.0f
float* pf = new float(2.0f);
//pc指针指向堆空间char变量,申请完后立即初始化为c
char* pc = new char('c');
//申请单个变量,将单个变量初始化为1
int *pi = new int(1);
//申请一片数组空间,这片数组的空间大小为1,pa所指向的是数组
int *pa = new int[1];
示例程序:(初始化动态内存)
#include <stdio.h>
int main()
{
//申请单个变量,将单个变量初始化为1
int *pi = new int(1);
//申请一片数组空间,这片数组的空间大小为1,pa所指向的是数组
//int *pa = new int[1];
float* pf = new float(2.0f);
char* pc = new char('c');
printf("*pi = %d\n", *pi);
printf("*pf = %f\n", *pf);
printf("*pc = %c\n", *pc);
delete pi;
delete pf;
delete pc;
return 0;
}
结果如下:
C++中的命名空间(解决全局变量命名冲突的问题)
(尽量不要使用全局变量。因为在工程开发中,有很多人进行开发,你和别人定义的全局变量冲突)
- 命名空间将全局作用域分成不同的部分
- 不同命名空间中的标识符可以同名而不会发生冲突
- 命名空间可以相互嵌套
- 全局作用域也叫默认命名空间
C++命名空间的定义:
/* C++命名空间的定义 */
namespace Name //将全局作用域进行划分,在全局作用域中有一块叫Name
{
namespace Internal //将刚刚所划分到的全局作用域,再进行划分
{
/* ...... */
}
/* ...... */
}
注意:无论怎么划分,它们的本质是全局作用域,在不同的命名空间里所定义的变量和函数,都是全局变量和全局函数。
C++命名空间的使用:
/* C++命名空间的使用 */
using namespace name; //使用整个命名空间
using name::variable; //使用命名空间中的变量
::variable; //使用默认命名空间中的变量
示例程序:(命名空间的使用)
#include <stdio.h>
//空间的划分,将全局作用域进行第一次划分,第一块全局作用域First
namespace First
{
int i = 0;//全局变量i
}
//将全局作用域划出第二块名为Second
namespace Second
{
int i = 1;//全局变量i
//在第二片命名空间里,又划分一小块出来,嵌套的命名空间Interval
namespace Interval
{
struct P
{
int x;
int y;
};
}
}
int main()
{
//表明将要在main函数里面使用First命名空间的“一切东西“
using namespace First;
//使用Second内部的Interval命名空间里的标识符P结构体
using Second::Interval::P;
//两个i是不同的,位于不同的命名空间中
printf("First::i = %d\n", i);
printf("Second::i = %d\n", Second::i);
P p = {2, 3};
printf("p.x = %d\n", p.x);
printf("p.y = %d\n", p.y);
return 0;
}
结果如下:
分析上述程序代码:两个i是全局变量,但是位于不同的命名空间,因此不冲突。
小结:
C++中内置了动态内存分配的专用关键字
C++中的动态内存分配可以同时进行初始化
C++中的动态内存分配是基于类型进行的
C++中的命名空间概念用于解决名称冲突问题