重载全局的new和delete
::operator new ::operator new[] -> 不可以被声明与同一个namespace
之内
new
会执行三个动作: -> 之前的代码提到:
-
new
本身会开辟内存空间.所以声明方法需要一个size_t size
的参数-
inline void* operator new(size_t size) {}
-
::operator delete ::operator delete[] -> 不可以被声明与同一个namespace
之内
-
delete
本身是归还内存的动作.所以需要接收一根指针-
inline void operator delete(void* ptr) {}
-
上述内容示例代码:
上述是全局的重载
class
当中的重载
调用代码:
另一种操作符重载:
调用代码:
上述代码可以看到new
这个动作会被分解为三个动作,会回到类当中寻找定义好的代码
强制调用全局的示例代码:
整体类设计示例:
注意:
-
上述代码当中调用了很多次的构造函数,那么实际开辟内存区域的时候变量
size_t
的大小会多一个int
类型数据大小 (counter
计数器)-> 该数据的值是调用的构造函数的次数 -
this
指针调用构造函数从counter
近的开始.析构函数从举例counter
远的开始 -> 这里没有画栈空间图所以口语化表达
可以重载全局、可以重载局部、还可以重载new()
-> 注意new
和new()
的区别 -> 并不是构造方法
重载new()
和delete()
-> 不要和构造函数混淆
特点:
-
每一个版本的
new()
的参数列都是独一无二 -
第一个参数固定是
size_t
-> 知道类的大小 -> 如果不是编译会报错 -
其余的参数以
new
指定的placement arguments
为初值
delete()
:
-
也可以重载
-
只有当重载的
new()
调用构造函数抛出异常的时候(new
这个动作被拆解成三步)才会调用这些重载的delete()
-
主要用来归还未能完全创建成功的
object
所占用的memory
示例代码:
调用字符串的new()
-> 如Foo * p = new(size) Foo
的操作.会返回计数器+size
大小的内容 -> 内存模型,拿到的其实是一根指针
-
这样就实现了悄无声息的多分配一些空间 -> 不仅仅是一根指针大小的空间
-
It's a lonely road!!!