[C++再学习系列] 深入new/delete:类域的operator new重载

简介:

类域的operator new重载

为 class 重载 operator new 时必须定义为类的静态函数 ( 默认为 static 函数 ) 。重载 operator new 更多的是为了提高程序效率,比如使用静态内存代替动态分配,启用小对象分配器等。但是要正确重载类域的 operator new 并不容易,有很多规则需要注意: 1) 总是成对提供 new/delete ; 2) 如重载 operator new 一定要同时提供标准形式的 new 。举例:

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);

};

T* p = new(alloc) T;

上述代码将被编译器展成下述代码 ( 猜测,如果有高人知道如何查看编译器生成的中间代码,烦请告知)

// compiler-generated code for T* p = new(alloc) T;

//

void* __compilerTemp = T::operator new (sizeof(T), alloc);  // 1

T* p;

try {

  p = new (__compilerTemp) T;      // 2 // construct a T at address __compilerTemp

}

catch(...) {                        // constructor failed, attention here…

  T::operator delete (__compilerTemp, sizeof(T), alloc);  // 3

  throw;

}

       注释 1 : operator new 用于分配内存, new 的第一步骤;

       注释 2 : placement new 用于在于地址上构建对象,也就是调用 T 的构造函数。

       注释 3 :与 operator new 配套的 operator delete 。

 

       C++ 标准规定:当且仅当 operator delete 的重载存在时,以上代码才能生成。否则,在构造函数失败的情况下,代码不会调用 operator delete 。也就是说,如果构造函数抛异常,内存将泄漏。

这意味着:当提供 void* operator new(parms) 重载时,必须同时提供 void operator delete(void*, parms), 这里参数列表的第一个参数总为 std::size_t 。 对于 operator new[] 也是如此。例外,对于 placement new 由于并不实际分配内存,可不重载相应的 operator delete 。

 重载opeartor new函数的隐藏

避免隐藏全局的operator new 和基类重定义的 operator new

       前面已经提到过 C++ 名字查找规则,对于重载的 operator new 也需要遵循此规则。当类中重载 operator new ,那么全局的operator new 将被隐藏;如果派生类重载 operator new ,那么基类的版本将被隐藏。由于 placement new 大量用于 STL 的优化中,故一定要避免隐藏 placement new 。隐藏 operator new 的这类错误编译器会给出提示。 

       重载 opeartor new 并避免隐藏全局 operator new 的途径:

       1) 对于基类重载的 operator new ,使用 using 来导入相应名字。

class C : public B {// …

public:

    static void* operator new(size_t, MemoryPool&); // private version

    using B::operator new;

       };

       2) 对一般重载 operator new 的类,除了提供私有版本外,应该对所有全局 operator new 形式提供转换函数。如下:

class C {// …

public:

static void* operator new(size_t, MemoryPool&);   // private version 

  static void* operator new(std::size_t s) {

  return ::operator new(s);        // global version

  }

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

  return ::operator new(s, nt);

  }

  static void* operator new(std::size_t s, void* p) {

  return ::operator new(s, p);

  }

};

相关文章:

深入new/delete:New的3种形态

深入new/delete:Operator new的全局重载

派生类函数的重实现规则(override-覆盖)

---------------------------------------------------

兄弟的公司:立即购--手机购物,诚信网购

兄弟的公司:立即团

欢迎转载,请注明作者和出处


本文转自 zhenjing 博客园博客,原文链接:http://www.cnblogs.com/zhenjing/archive/2011/01/17/class_new.html  ,如需转载请自行联系原作者

相关文章
|
5月前
|
安全 C语言 C++
比较C++的内存分配与管理方式new/delete与C语言中的malloc/realloc/calloc/free。
在实用性方面,C++的内存管理方式提供了面向对象的特性,它是处理构造和析构、需要类型安全和异常处理的首选方案。而C语言的内存管理函数适用于简单的内存分配,例如分配原始内存块或复杂性较低的数据结构,没有构造和析构的要求。当从C迁移到C++,或在C++中使用C代码时,了解两种内存管理方式的差异非常重要。
197 26
【C++】深入解析C/C++内存管理:new与delete的使用及原理(二)
【C++】深入解析C/C++内存管理:new与delete的使用及原理
210 4
|
编译器 C++ 开发者
【C++】深入解析C/C++内存管理:new与delete的使用及原理(三)
【C++】深入解析C/C++内存管理:new与delete的使用及原理
243 3
|
存储 C语言 C++
【C++】深入解析C/C++内存管理:new与delete的使用及原理(一)
【C++】深入解析C/C++内存管理:new与delete的使用及原理
281 3
|
12月前
|
算法 网络安全 区块链
2023/11/10学习记录-C/C++对称分组加密DES
本文介绍了对称分组加密的常见算法(如DES、3DES、AES和国密SM4)及其应用场景,包括文件和视频加密、比特币私钥加密、消息和配置项加密及SSL通信加密。文章还详细展示了如何使用异或实现一个简易的对称加密算法,并通过示例代码演示了DES算法在ECB和CBC模式下的加密和解密过程,以及如何封装DES实现CBC和ECB的PKCS7Padding分块填充。
261 4
2023/11/10学习记录-C/C++对称分组加密DES
|
11月前
|
C++ 开发者
C++学习之继承
通过继承,C++可以实现代码重用、扩展类的功能并支持多态性。理解继承的类型、重写与重载、多重继承及其相关问题,对于掌握C++面向对象编程至关重要。希望本文能为您的C++学习和开发提供实用的指导。
165 16
|
编译器 C语言 C++
配置C++的学习环境
【10月更文挑战第18天】如果想要学习C++语言,那就需要配置必要的环境和相关的软件,才可以帮助自己更好的掌握语法知识。 一、本地环境设置 如果您想要设置 C++ 语言环境,您需要确保电脑上有以下两款可用的软件,文本编辑器和 C++ 编译器。 二、文本编辑器 通过编辑器创建的文件通常称为源文件,源文件包含程序源代码。 C++ 程序的源文件通常使用扩展名 .cpp、.cp 或 .c。 在开始编程之前,请确保您有一个文本编辑器,且有足够的经验来编写一个计算机程序,然后把它保存在一个文件中,编译并执行它。 Visual Studio Code:虽然它是一个通用的文本编辑器,但它有很多插
496 6
|
程序员 C语言 C++
C++入门5——C/C++动态内存管理(new与delete)
C++入门5——C/C++动态内存管理(new与delete)
250 1
|
Java 编译器 C++
c++学习,和友元函数
本文讨论了C++中的友元函数、继承规则、运算符重载以及内存管理的重要性,并提到了指针在C++中的强大功能和使用时需要注意的问题。
156 1
C++(十九)new/delete 重载
本文介绍了C++中`operator new/delete`重载的使用方法,并通过示例代码展示了如何自定义内存分配与释放的行为。重载`new`和`delete`可以实现内存的精细控制,而`new[]`和`delete[]`则用于处理数组的内存管理。不当使用可能导致内存泄漏或错误释放。