new和delete
int* p0 = new int; //创建一个int的空间
delete p0;
int* p1 = new int[10];//创建一个10个int的数组,默认都是随机值
delete[] p1;
int* p2 = new int(5);//创建一个int的空间,并初始化为5
delete p2;
//C++11才支持这种写法,C++98不支持
int* p3 = new int[5] {1, 2, 3};//创建一个5个int的数组,类似数组的不完全初始化
delete[] p3;
对于内置类型,malloc/free和new/delete本质没什么区别,只是用法简化了。
class Stack
{
public:
Stack(int capacity = 4)
:_a(nullptr)
, _top(0)
, _capacity(capacity)
{
_a = new int[capacity];
}
~Stack()
{
delete[] _a;
_a = nullptr;
_top = _capacity = 0;
}
private:
int* _a;
int _top;
int _capacity;
};
int main()
{
Stack* ps = (Stack*)malloc(sizeof(Stack));
//ps->Stack(); 报错
ps->~Stack();
free(ps);
//不能显式调用构造,可以显式调用析构
return 0;
}
对于自定义类型,除了申请空间,还需要调用构造函数初始化,但构造函数无法显式调用,所以就有了new,new是为了解决自定义类型申请空间后的初始化问题。new在堆上申请空间并调用构造函数初始化,delete会调用析构函数清理资源并释放空间。
operator new 和 operator delete
operator new 和 operator delete 是系统提供的全局函数。
operator new 帮助new开空间,封装malloc,符合C++new的失败抛异常机制。operator delete帮助delete释放空间,封装free。
new = operator new{malloc(有抛异常机制)} + 构造初始化
delete = 析构清理资源 + operator delete{free(有抛异常机制)}
定位new
如果开了空间,想要调用构造函数的话,可以使用定位new
语法:
new(指针)自定义类型(参数列表)
new(指针)自定义类型
class Stack
{
public:
Stack(int capacity = 4)
:_a(nullptr)
, _top(0)
, _capacity(capacity)
{
_a = new int[capacity];
}
~Stack()
{
delete[] _a;
_a = nullptr;
_top = _capacity = 0;
}
private:
int* _a;
int _top;
int _capacity;
};
int main()
{
Stack* ps = (Stack*)operator new(sizeof(Stack));
new(ps) Stack(4); //定位new
return 0;
}
int main()
{
Stack* ps = new Stack;
//new做了下面两句的工作
Stack* ps = (Stack*)operator new(sizeof(Stack));
new(ps) Stack();
delete ps;
//delete做了下面两句的工作
ps->~Stack();
operator delete(ps);
return 0;
}
malloc/free和new/delete的区别
1.malloc和free是函数,new和delete是操作符
2.malloc申请的空间不会初始化,new可以
3.malloc申请空间时,需要手动计算空间大小并传递,new只需在其后跟上空间类型即可,如果是多个对象,[]中指定对象个数即可
4.malloc的返回值为void*,需要手动强转,new不需要,因为new后面跟着空间的类型
5.malloc失败返回空指针,new失败抛异常
6.对于自定义类型,malloc和free只会申请和释放空间,new在堆上申请空间并调用构造函数初始化,delete会调用析构函数清理资源并释放空间。