C++编程规范指46:如果提供专门的new,应该提供所有标准形式(普通、就地和不抛出)

简介:

摘要:

    不要隐藏好的new:如果类定义了operatornew 的重载,就应该提供operator new 所有三种形式——普通(plain)、就地(in-place)和不抛出(nothrow)的重载。

    很少需要提供自定义的new 或者delete,但是如果确实需要,通常也不想隐藏内置的签名。

C++中,在某个作用域(比如一个类作用域)里定义了一个名字之后,就会隐藏所有外围作用域中(如,在基类或者外围名字空间)同样的名字,而且永远不会发生跨作用域的重载。当上述名字是operator new时,需要特别小心,以免对类的客户产生不良影响。

    假设我们定义了一个类专门的operatornew:

Class C

{

         //……

         Static void* operatornew(size_t,void*);//隐藏三种常规形式

};

    然后,如果有人试图编写一个和普通旧式newC一样无趣的表达式,编译器会拒绝对其进行编译,其根据是无法找到普通旧式的operator new。生命接受一个memorypool为参数的C::operator new重载,将隐藏所有其他重载,包括我们都熟知而且爱用的内置全局版本,也就是:

Void* operatornew(std::size_t);//普通new

Void* operatornew(std::size_t,std::nothrow_t) throw();//不抛出new

Void* operatornew(std::size_t,void*);//就地new

    或者,类也可能对以上三种operatornew 之一提供自己专用的版本。在此情况下,如果声明了其中之一,默认时类将屏幕其他两个:

Class C

{

         //……

         Static void* operatornew(size_t,void*);//隐藏其他两种常规形式

};

    应该让类C在作用域中显式地声明operatornew 的所有三种标准变体。通常,所有三种形式都有相同的可见性。(各个形式还可以将可见性设为private,比如要显示地禁用普通或者不抛出operator new,但是本条款的目的是提醒读着记住不要因为疏忽而隐藏它们。)

    请注意,应该总是避免就地new,因为它在STL容器中有广泛的使用。

    最后一个技巧是:在两种不同的环境下,公开已隐藏的operator new需要采用来年各种不同的方式。如果类的基类也定义了operator new,那么要公开operator new所需做的就是:

Class C:public B

{

         //……

         Public:

         Using B::operator new;

};

    否则,如果没有基类版本或者基类没有定义operatornew,就需要写一些短小的转送函数(因为无法通过using从全局名字空间中导入名字):

Class C

{

         //……

         Public:

         Static void* operator new(std::size_t s)

         {

                   Return ::operator new(s);

}

Static void* operator new(std::size_t s,std::nothrow_t nt) throw()

{

         Return ::operator new(s,p);

}

};

    上面的建议也适用于数组形式的operatornew[]和operator delete[]。

    避免在客户代码中国调用new(nothrow)版本,但是仍然要为客户提供,以免客户一旦要用到时感到奇怪。

目录
打赏
0
0
0
0
21
分享
相关文章
|
6月前
|
C++
【C++】深入解析C/C++内存管理:new与delete的使用及原理(二)
【C++】深入解析C/C++内存管理:new与delete的使用及原理
110 4
【C++】深入解析C/C++内存管理:new与delete的使用及原理(三)
【C++】深入解析C/C++内存管理:new与delete的使用及原理
135 3
【C++】深入解析C/C++内存管理:new与delete的使用及原理(一)
【C++】深入解析C/C++内存管理:new与delete的使用及原理
151 2
C++入门5——C/C++动态内存管理(new与delete)
C++入门5——C/C++动态内存管理(new与delete)
134 1
|
7月前
|
C++
C++(十九)new/delete 重载
本文介绍了C++中`operator new/delete`重载的使用方法,并通过示例代码展示了如何自定义内存分配与释放的行为。重载`new`和`delete`可以实现内存的精细控制,而`new[]`和`delete[]`则用于处理数组的内存管理。不当使用可能导致内存泄漏或错误释放。
c++开发redis module问题之如果Redis加载了多个C++编写的模块,并且它们都重载了operator new,会有什么影响
c++开发redis module问题之如果Redis加载了多个C++编写的模块,并且它们都重载了operator new,会有什么影响
c++学习笔记08 内存分区、new和delete的用法
C++内存管理的学习笔记08,介绍了内存分区的概念,包括代码区、全局区、堆区和栈区,以及如何在堆区使用`new`和`delete`进行内存分配和释放。
85 0
【C/C++】动态内存管理( C++:new,delete)
C++的`new`和`delete`用于动态内存管理,分配和释放内存。`new`分配内存并调用构造函数,`delete`释放内存并调用析构函数。`new[]`和`delete[]`分别用于数组分配和释放。不正确匹配可能导致内存泄漏。内置类型分配时不初始化,自定义类型则调用构造/析构。`operator new`和`operator delete`是系统底层的内存管理函数,封装了`malloc`和`free`。定位`new`允许在已分配内存上构造对象,常用于内存池。智能指针等现代C++特性能进一步帮助管理内存。
c++开发redis module问题之避免多个C++模块之间因重载operator new而产生的冲突,如何解决
c++开发redis module问题之避免多个C++模块之间因重载operator new而产生的冲突,如何解决
|
9月前
|
C++
C++基础知识(二:引用和new delete)
引用是C++中的一种复合类型,它是某个已存在变量的别名,也就是说引用不是独立的实体,它只是为已存在的变量取了一个新名字。一旦引用被初始化为某个变量,就不能改变引用到另一个变量。引用的主要用途包括函数参数传递、操作符重载等,它可以避免复制大对象的开销,并且使得代码更加直观易读。
AI助理

你好,我是AI助理

可以解答问题、推荐解决方案等