C++编程规范之45:总是一起提供new和delete

简介:

摘要:

它们是一揽子交易:每个类专门的重载void*operator new(parms)都必须与对应的重载void operator delete(void*, params)相随相伴,其中parms是额外参数类型的一个列表(第一个总是std:size_t)。数组形式的new[]和delete[]也同样如此。

    很少需要提供自定义的new或者delete,但是如果需要其中一个,那么通常两个都需要。如果定义了类专门的T::operator new进行某种特殊的分配操作,很可能还需要定义一个类专门的T::operator delete进行相应的释放操作。

    这些阐述可能有些过于基础了,但是之所以要加入本条款,有一个更加微妙的原因:编译器可能需要T::operator delete的重载,即使实际上从来也不会调用它。这才是为什么要成对提供operator new和operator delete(以及operator new[]和operator delete[])的原因。

    假设定义了一个带有自定义分配操作的类:

class T

{

         //……

         Static void* operator new(std::size_t)

         Static void* operator new(std::size_t,CustomAllocator&)

 

         Static void operator delete(void*,std::size_t)

};

这样就为分配和释放建立了一个简单的协议。

1.调用者能够用默认的分配器(使用new T)或者自定义的分配器,(使用new(alloc)T,其中alloc是一个customAllactor类型的对象)来分配类型T的对象。

2.唯一调用者可能调用的operatordelete是默认的operator delete(size_t),因此当然应该实现,从而能够正确地释放已分配的内存。

到目前为止,一切正常。

但是编译器冉冉需要秘密地调用另一个delete重载,即T::operatordelete(size_t, CustomAllocator&)。这是因为语句

T* p = new(alloc)T;

实际上将扩展为类似下面的代码:

//编译器为T* p =new(alloc)T;生成的代码

//

Void*_compilerTemp = T::operator new (sizeof(T),alloc);

T* p;

Try

{

         P = new(_compilerTemp)T;

}

Catch(…)

{

         T::operator delete(_compilerTemp,sizeof(T), alloc);

         throw

}

    因此,如果分配成功,但是构造函数失败了,那么编译器将顺理成章地自动插入代码,为重载的T::operator new调用对应的T::operator delete。对应的签名是void operator delete(void*,whatever-parameters-new-takes).

    下面是煞风景的部分了。C++ Standard规定,当且仅当operatordelete的重载实际退出时,以上代码才能生成。否则,在构造函数失败的情况下,代码不会调用任何operator delete。也就是说,如果构造函数失败,内存将泄漏。

    正因为如此,重载void*operator new(parms)必须伴有与其对应的重载void operator delete(void* ,params)——因为编译器自己要调用它们。

相关文章
|
4天前
|
存储 Java 编译器
C++:内存管理|new和delete
C++:内存管理|new和delete
|
4天前
|
存储 算法 编译器
【C++ 内存管理 重载new/delete 运算符 新特性】深入探索C++14 新的/删除的省略(new/delete elision)的原理与应用
【C++ 内存管理 重载new/delete 运算符 新特性】深入探索C++14 新的/删除的省略(new/delete elision)的原理与应用
65 0
|
4天前
|
存储 安全 Java
C++ delete语句
C++ delete语句
6 0
|
4天前
|
存储 算法 测试技术
|
4天前
|
程序员 编译器 C++
|
4天前
|
存储 编译器 C++
【C++】内存管理和模板基础(new、delete、类及函数模板)
【C++】内存管理和模板基础(new、delete、类及函数模板)
25 1
|
4天前
|
安全 程序员 C++
C++ new和delete的用法
需要注意的是,使用 `new`和 `delete`分配和释放内存时,程序员负责管理内存的分配和释放,这可能导致内存泄漏或释放已释放内存的问题。因此,C++引入了智能指针(如 `std::shared_ptr`和 `std::unique_ptr`)以更安全和自动化地管理内存。
36 2
|
4天前
|
C语言 C++
【C++基础(九)】C++内存管理--new一个对象出来
【C++基础(九)】C++内存管理--new一个对象出来
|
4天前
|
存储 Linux C语言
【C++练级之路】【Lv.5】动态内存管理(都2023年了,不会有人还不知道new吧?)
【C++练级之路】【Lv.5】动态内存管理(都2023年了,不会有人还不知道new吧?)
|
4天前
|
算法 前端开发 大数据
【C/C++ 基础知识 】C++中易混淆的函数和关键字:std::find vs std::search,std::remove vs std::erase,remove vs delete
【C/C++ 基础知识 】C++中易混淆的函数和关键字:std::find vs std::search,std::remove vs std::erase,remove vs delete
36 0