c++ new与delete操作

C++ new和delete内存分配

在C语言中我们使用的是malloc与free函数来分配内存,但Malloc分配内存需要自己定义分配的长度,这样十分不方便,于是c++中推出了new与delete来将对象放置在特定的内存空间中,它能够自动根据分配内存的对象分配内存大小。

基本操作

string a = new string; //分配一个string类型的对象
string *b= new string[10]; //分配10个默认初始化的string对象

delete a;
delete [] b; //删除数组要加[]

内存分配分为三个步骤:

步骤 操作
1 new 表达式调用函数库中 operator new (或operator new [ ])函数分配一块原始空间,在这块空间中中没有任何东西,只是一个容器,
2 编译器运行相应的构造函数构造相应对象,传入初值
3 返回指向对象的指针

内存的销毁分为两个步骤

步骤 操作
1 调用相应的析构函数将内存中的对象析构
2 编译器调用operate delete [ ](或operator delete)释放内存空间

中级操作

我们可以不通过new与delete来一步实现,而是通过手动一步步实现,在实际应用当中这样做也是有实际意义的:

class A
{
pubilc:
	A(int a);
	~A();
}:

实际项目中,并不是每个类都是需要默认构造函数的,只有当类中初始化的变量有意义时我们才会写默认构造函数,但假如这个类初始化是没有任何意义的时候(比如仪器公司规定每一个生产仪器都需要有一个编号,如果没有编号,这个仪器就毫无意义),那么我们的构造函数都需要一个变量。
但没有默认构造函数我们的程序就会变得比较难写

A a[10];
A *a = new A[10];

因为没有默认构造函数,所以这种写法无法编译,假如我们需要创建一个类的数组需要用下面这种方式创建

class A  
{
public:
	A(int a){
		std::cout << "call A constructor" << std::endl;
	}
	~A(){
		std::cout << "call A destructor" << std::endl;
	}
};
int main()
{
	void *RawMomery = operator new[](10 * sizeof(A)); //第一步开辟一个10*A大小的内存空间
	A *Basement = static_cast<A *>(RawMomery); //转换RawMomery数据类型为*A并赋值给basement
	for (int i = 0; i < 10; i++) {
		new(&Basement[i]) A(1); // placement new (能够定位放置new):在BaseMent[i]处创建A(1)
	}
	for (int i = 0; i < 10; i++) {
		Basement[i].~A(); //析构BaseMent数组中的元素
	}
	operator delete[](RawMomery); //释放内存
	return 0;
}

这么做可以提高class效率,防止无意义字段产生。

高级操作

C++是一门非常灵活的语言,它还可以通过自定义opeartor new与operator delete函数对内存分配的过程进行控制。当编译器找到一个new或delete函数的时候,就会查找整个程序中的operator new(operator delete)函数(先在类与基类中查找,之后在全局作用域查找)找到则使用 我们自己写的函数(使用::new或::delete可直接在全局作用域查找)

class A  
{
public:
	A(int a){
		std::cout << "call A constructor" << std::endl;
	}
	void *operator new (size_t size);
	void operator delete(void *dead ) noexcept;
	~A(){
		std::cout << "call A destructor" << std::endl;
	}
};
void *A::operator new(size_t size  ){
	cout << "调用了A::operator new   " <<endl;
	A *p=(A*)malloc(sizeof(A));
	return p;
}
void A::operator delete(void *dead) noexcept {
	cout << "调用了A::operator delete" << endl;
	free(dead);
}
int main()
{
	A *p = new A(1);
	//A *p = ::new A(1);
	delete p;
	//::delete p;
	return 0;
}

如果有什么不足,希望大佬指正

发布了5 篇原创文章 · 获赞 0 · 访问量 84

猜你喜欢

转载自blog.csdn.net/weixin_43791996/article/details/105159189