1 new与delete的使用
在C++中,申请和释放堆中分配的存贮空间,分别使用new和delete的两个运算符来完成,其使用的格式如下:
对于单个对象:
指针变量名=new 类型名(初始化式)
int *p = new int(10);
delete p;
对于数组进行动态分配的格式:
指针变量名=new 类型名[下标表达式];
int *p = new int[10]
delete [] p;
注意点:
1、对于多维数组的的delete也只需加一个[],[]中无需填写数组的大小
2、由new创建对象数组,只能调用缺省的构造函数,不能调用其他任何构造函数。如果没有缺省的构造函数,则不能创建对象数组,即在new创建对象数组时,不能进行初始化操作 int *p = new int[10](0) // error
2 new/delete 与 malloc/free的区别
/*
1 new 在申请空间是无需指定申请空间的大小,会由类型自己判断
2 new 返回的指针类型在赋值时无需强转
3 若new失败不必做异常判断,申请空间失败会抛出异常
4 new在申请对象空间时,除了空间的申请,还会调用对象的构造函数
即调用operator new()函数和构造函数,operator new函数编译器会提供,
operator new函数还可以人为的重载,
*/
int *p = new int(0);
int *q = (int*)malloc(sizeof(int));
if(q == NULL)
return;
// delete对象时除了释放空间,还会调用对象的析构函数
delete p;
free(q);
3 new 与 delete的重载与调用
#define _CRT_SECURE_NO_WARNINGS
#include <iostream>
#include <string>
using namespace std;
// new 运算符的重载,只是申请空间
void* operator new(size_t size)
{
cout << "operator new" << endl;
void *p = malloc(size);
return p;
}
// delete 运算符的重载,只是释放空间
void operator delete(void *p)
{
cout << "operator delete" << endl;
free(p);
}
// new[] 运算符的重载, 只是申请空间
void* operator new[](size_t size)
{
cout << "operator new[]" << endl;
void *p = malloc(size);
return p;
}
// delete[] 运算符的重载,只是释放空间
void operator delete[](void *p)
{
cout << "operator delete[]" << endl;
free(p);
}
class String
{
public:
String(char *d = "")
{
cout << "Create String" << endl;
if (d == NULL)
{
data = new char[1];
data[0] = '\0';
}
else
{
data = new char[strlen(d) + 1];
strcpy(data, d);
}
}
~String()
{
cout << "Free String" << endl;
delete []data;
}
void PrintString()const
{
cout << data << endl;
}
private:
char *data;
};
int main()
{
// error 申请数组空间时只能调用无参数的构造函数,不能有参初始化
String *sArr = new String[10]("hello");
String *s = new String("hello");
// s->PrintString();
delete s;
system("pause");
return 0;
}
结果分析:
operator new:new运算符重载,先调用 void* operator new(size_t)申请空间,
Create String:调用对象的构造函数,完成new运算符的空间申请+对象构造
operator new[]:调用对象的构造函数时,new char[] 重载函数的调用
Free String:delete对象时,先调用对象的析构函数
operator delete[]:析构函数内部,delete[] data 重载函数的调用
operator delete:完成对象的析构后,最后释放空间。完成delete运算符的对象析构+空间释放
注意:
1、new对象时是先申请空间再构造对象,delete对象时是先析构对象再释放空间
2、new 与 delete也可以在对象的内部重载,即重载成成员函数,当new与delete有重载时,调用优先级为优先调用成员函数的new/delete重载函数,若成员函数没有重载,则调用全局函数的new/delete重载函数,若new/delete没有重载,则调用编译器提供的new/delete函数