2024年最全c++ 内存管理二:重载(接管内存管理工具)_c(3),真正带你搞懂RecyclerView的缓存机制

img
img

既有适合小白学习的零基础资料,也有适合3年以上经验的小伙伴深入学习提升的进阶课程,涵盖了95%以上C C++开发知识点,真正体系化!

由于文件比较多,这里只是将部分目录截图出来,全套包含大厂面经、学习笔记、源码讲义、实战项目、大纲路线、讲解视频,并且后续会持续更新

如果你需要这些资料,可以戳这里获取

}

void Foo::operator delete(void* pdead, size_t size)
{
cout << "Foo::operator delete(), pdead= " << pdead << " size= " << size << endl;
free(pdead);
}

void* Foo::operator new[](size_t size)
{
Foo* p = (Foo*)malloc(size); //crash, 問題可能出在這兒
cout << “Foo::operator new, size=” << size << "\t return: " << p << endl;

return p;

}

void Foo::operator delete[](void* pdead, size_t size)
{
cout << "Foo::operator delete, pdead= " << pdead << " size= " << size << endl;

free(pdead);

}

void test_overload_operator_new_and_array_new()
{
cout << “\ntest_overload_operator_new_and_array_new()… \n”;

cout << "sizeof(Foo)= " << sizeof(Foo) << endl;

{	
Foo\* p = new Foo(7);
delete p;

Foo\* pArray = new Foo[5];	//無法給 array elements 以 initializer 
delete [] pArray;	
}

{	    
cout << "testing global expression ::new and ::new[] \n";
// 直接调用全局的 ::new 这会绕过 overloaded new(), delete(), new[](), delete[]() 
// 但 ctor, dtor 都会被正常调用. 

Foo\* p = ::new Foo(7);
::delete p;

Foo\* pArray = ::new Foo[5];	
::delete [] pArray;
}

}


#### 3 重载类的带有额外参数的 operator new 运算符



void* operator new(std::size_t size, AdditionalArgs args) {
// 自定义内存分配逻辑,可以使用额外的参数
void* ptr = /* 自定义逻辑 */;
return ptr;
}


通过重载带有额外参数的 `operator new`,我们可以在内存分配过程中传递额外的参数,以便进行更复杂的内存管理。


在重载 `operator new` 运算符时,注意以下几点:


* 返回值类型必须为 `void*`,表示分配的内存地址。
* 第一个参数是 `std::size_t size`,表示要分配的内存大小。
* 可以有额外的参数,以满足特定需求。
* 可以使用任何自定义的内存分配逻辑,例如使用 `malloc`、内存池等。
* 注意处理错误和异常情况,确保内存分配成功。


示例代码



class Foo
{
public:
Foo() { cout << “Foo::Foo()” << endl; }
Foo(int) {
cout << “Foo::Foo(int)” << endl;
}

//(1) 这个就是一般的 operator new() 的重载
void\* operator new(size_t size) {
	cout << "operator new(size\_t size), size= " << size << endl;
	return malloc(size);  
}

//(2) 这个就是标准库已经提供的 placement new() 的重载 (形式)
void\* operator new(size_t size, void\* start) { 
  	cout << "operator new(size\_t size, void\* start), size= " << size << " start= " << start << endl;
	return start;
}

void\* operator new(size_t size, long extra) { 
  	cout << "operator new(size\_t size, long extra) " << size << ' ' << extra << endl;
	return malloc(size+extra);
}

void\* operator new(size_t size, long extra, char init) { 
  	cout << "operator new(size\_t size, long extra, char init) " << size << ' ' << extra << ' ' << init << endl;
	return malloc(size+extra);
}

//(1) 这是对应一般的 operator delete() 的重載 
void operator delete(void\*,size_t)
{ cout << "operator delete(void\*,size\_t) " << endl;  }

//(2) 这是对应上述的 (2) 
void operator delete(void\*,void\*)
{ cout << "operator delete(void\*,void\*) " << endl;  }

//(3) 这是对应上述的 (3) 
void operator delete(void\*,long)
{ cout << "operator delete(void\*,long) " << endl;  }

//(4) 这是对应上述的 (4) 
//如果沒有一一对应, 也不会有任何编译错误
void operator delete(void\*,long,char)
{ cout << "operator delete(void\*,long,char) " << endl; }

private:
int m_i;
};

void test_overload_placement_new()
{
cout << “\n\n\ntest_overload_placement_new()… \n”;

Foo start;  //Foo::Foo

Foo\* p1 = new Foo;           //op-new(size\_t)
Foo\* p2 = new (&start) Foo;  //op-new(size\_t,void\*)
Foo\* p3 = new (100) Foo;     //op-new(size\_t,long)
Foo\* p4 = new (100,'a') Foo; //op-new(size\_t,long,char)

Foo\* p5 = new (100) Foo(1);     //op-new(size\_t,long) op-del(void\*,long)
Foo\* p6 = new (100,'a') Foo(1); //
Foo\* p7 = new (&start) Foo(1);  //
Foo\* p8 = new Foo(1);           //

}


![在这里插入图片描述](https://img-blog.csdnimg.cn/8defeb30c05f4399a010dcbc6ecab940.png)



> 
> //VC6 warning C4291: ‘void \*\_\_cdecl Foo::operator new(unsigned int)’  
>  //no matching operator delete found; memory will not be freed if  
>  //initialization throws an exception
> 
> 
> 


这表示对对应的new调用的构造函数的异常不做处理。所以这里delete参数实际上是对应异常的类型。


将构造函数抛出异常,然后打印。**这里要注意将调用的代码即`test_overload_placement_new`使用try catch包含,否则无法捕获异常。**



Foo(int) {
cout << “Foo::Foo(int)” << endl;
throw 1;
}


可以看到,`operator delete(void*,long)`是执行了。  
 当然异常抛出以后后面的自然也就不执行了。  
 ![在这里插入图片描述](https://img-blog.csdnimg.cn/6b37a32ab9b842008444477e566c9fbe.png)


#### 4 单类重载new的优化示例


![img](https://img-blog.csdnimg.cn/img_convert/fb707cdb23a65a1a5fd88db185cc9a09.png)
![img](https://img-blog.csdnimg.cn/img_convert/fe469daa28a83f25de8574d8a8ccbe17.png)

**既有适合小白学习的零基础资料,也有适合3年以上经验的小伙伴深入学习提升的进阶课程,涵盖了95%以上C C++开发知识点,真正体系化!**

**由于文件比较多,这里只是将部分目录截图出来,全套包含大厂面经、学习笔记、源码讲义、实战项目、大纲路线、讲解视频,并且后续会持续更新**

**[如果你需要这些资料,可以戳这里获取](https://bbs.csdn.net/topics/618668825)**

*既有适合小白学习的零基础资料,也有适合3年以上经验的小伙伴深入学习提升的进阶课程,涵盖了95%以上C C++开发知识点,真正体系化!**

**由于文件比较多,这里只是将部分目录截图出来,全套包含大厂面经、学习笔记、源码讲义、实战项目、大纲路线、讲解视频,并且后续会持续更新**

**[如果你需要这些资料,可以戳这里获取](https://bbs.csdn.net/topics/618668825)**

  • 4
    点赞
  • 6
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值