博主简介:
本博主是大二在读生,主要学习后端方向的知识。
博主的博客主页:CSND博客
Gitee主页:博主的Gitee
博主的稀土掘金:稀土掘金主页
博主的b站账号:程序员乐
new就是在堆区开辟一段空间。
new和c语言中的动态内存开辟不一样——malloc
,new是一个操作符
delete就是对申请空间的释放,也是一个操作符。
下面是它的一些写法。
#include
using namespace std;
int main()
{
int* ptr1 = new int;//没有初始化
int* ptr2 = new int(1);//把申请的内存里面的数据初始化为1
int* ptr3 = new int[3];//动态申请3个int类型的空间
int* ptr4 = new int[3]{ 1,2,3 };//动态申请3个int类型的空间,并对相应的空间进行初始化
return 0;
}
当然也有申请失败的时候,c语言中申请失败返回空指针,c++中会抛出异常。
new和delete会在创建/销毁对象的时候分别调用构造函数,析构函数。这个用
malloc
不能实现的(成员函数私有的时候,想要实现可以用定位new)
class A
{
public:
A()
{
cout << "A()" << endl;
}
~A()
{
cout << "~A()" << endl;
}
};
int main()
{
A* a = new A;
delete a;
return 0;
}
注意:
释放的形式要和申请的形式一样
A* a = new A;
delete a;
A* b = new A[4];
delete[] b;
当然对于自定义类型也可以初始化,就是在创建类型的后面用小括号或者大括号给予初始的值。
class Date
{
public:
Date(int year=1)
:_year(year)
{
cout << _year << endl;
}
private:
int _year;
};
int main()
{
Date* a = new Date(2022);
Date* b = new Date[5]{ 2000,2001,2002,2003,2004 };
return 0;
}
没有用new进行开辟空间,而是用c语言中的
malloc
等函数实现的,此时是不会自动调用构造函数的。
定位new的形式
new(申请空间的地址)类型
使用定位new可以解决这个问题。
class A
{
public:
A(int t=0)
:x(t)
{
cout << "A()" << x << endl;
}
~A()
{
cout << "~A()" << endl;
}
private:
int x;
};
int main()
{
A* a = (A*)malloc(sizeof(A));
new(a)A(1);//这样就可以调用构造函数,进行初始化
a->~A();//要想调用析构函数就这样显式调用
free(a);//因为不是new申请的,所以不能用delete进行释放,
//还是用free进行释放
return 0;
}
new
会调用operator new
,operator new
最终去调用malloc
,只不过在里面实现的时候,没有开辟成功会抛异常罢了。
delete
会调用operator delete
,operator delete
最终会调用free
。
底层代码后期再贴。