首页 C++内存管理- 9~11
文章
取消

C++内存管理- 9~11

C++内存管理 - 9~11

此笔记需要等待更新和确认。

重载 operator new, operator delete

微信图片_20220531035654

注意红色的是较为常见的重载成员函数中的operator new。绿色的是不常见的重载全局函数的operator new

重载全局operator new, operator delete

微信图片_20220531040706

  • 一定要注意,全局的::operator new下面是malloc。全局的::operator delete下面是free。所以全局::operator new不构造对象,全局::operator delete也不析构对象。

注意事项

重载operator new的时候一定要注意 它的返回类型必须是void*

请注意,任何指针都可以赋值给void指针。不需要转换。只获得变量/对象地址而不获得大小。 如以下代码:

1
2
3
4
5
6
7
8
9
10
11
void* test(int* a){
    *a = 4;
    return a;
}
int main(){
    int s = 1;
    int* b = &s;
    test(b);
    cout << s << endl;
}
//输出结果为4

QQ截图20220531044057

重载局部(某个类内)operator new, operator delete

QQ截图20220531041338

注意重载局部operator new, operator delete必须要设置为静态函数

注意重载局部operator new, operator delete必须要设置为静态函数。因为为对象分配内存的时候是正在创建对象,而没有对象无法调用类非静态成员。所以为了用类的函数进行内存分配,必须要把new和delete设置为类的静态函数这样可以在没有创建对象之前就调用。

**任何类内的内存分配函数必须要声明为静态函数 static **

静态成员函数即使在类对象不存在的情况下也能被调用,静态函数只要使用类名加范围解析运算符 :: 就可以访问。new对象时,对象还没有,设置成类非静态成员函数是没意思的,隐藏的this指针无从下手,所以要声明为static函数。

  • 此时,如果想使用全局的operator new则需要加作用域访问运算符:指定全局作用域

  • 这里多提一嘴。看一下这个的内存池实现这个

more effective c++ 条款8 了解new operator 和 operator new 的区别

注意,重载的类内operator new 和 delete是在我们使用new (这个new叫做 new operator)的时候,编译器在new的底下会调用我们重载的operator new。我们本身如果直接调用operator new不会调用构造函数,因为我们此时不能手动调用对象初始化所必须的构造函数。

new operator会执行底层的operator new,然后如memory1中提到的帮助我们转型和构造。

delete operator会执行底层的operator delete,然后如memory1中提到的帮助我们析构。

  • 所以,如果想分配内存并构造对象,则依旧使用new。如果只想分配内存,不构造对象,则可以手动调用operator new

  • 所以,直接调动全局的::operator new不会调用构造函数。因为它的下面只是malloc。直接调用全局的::operator delete不会调用析构函数。因为它的下面只是free

顺便一提,根据标准,针对单对象或数组的分配函数(也就是局部operator newoperator new[])对这些函数不需要使用关键词 static。不管是否显式使用(声明分配函数为静态),分配函数都是静态成员函数。

QQ截图20221217071624

重载 operator new() delete()。这个地方指的是重载placement new

重载operator new() 的时候一定要注意,有多个版本的时候每一个重载版本都要有独特的不一样的参数列表。而且参数列表的第一个参数必须是size_t 剩下的参数必须不一样。 而且 它的返回类型必须是void*,并不必须重载operator delete()。查看discord频道笔记。关键字new()

记住笔记二中说的,placement new 是operator new的一种特殊形式

QQ截图20220531042442

本文由作者按照 CC BY 4.0 进行授权