[C++再学习系列] 深入new/delete:New的3种形态

简介:

New3种形态: new operator、operator newplacement new

new操作符 (new表达式 new operator , new expression): 通常我们调用 X * pX = new X 时使用的就是这个操作符 由语言内建 不能重载 不能改变其行为 包括分配内存的 operator new 和调用构造函数的 placement new  new关键字实际上做了三件事:获得一块内存空间、调用构造函数、返回正确的指针。当然,如果我们创建的是简单类型的变量,那么第二步会被省略。

operator new : operator new 是一个函数 , void * operator new(size_t size) 。它分配指定大小的内存 可以被重载 可以添加额外的参数 但第一个参数必须为 size_t 。 operator new 除了被 new operator 调用外也可以直接被调用 : void * rawMem = operator new(sizeof(X)) 。这种用法和调用 malloc 一样。

placement new : placement new 在一块指定的内存上调用构造函数 包含头文件 <new> 之后也可以直接使用 placement new: X * pX = new (rawMem) X 。 

与 new operator 类似 对于 delete operator, 也存在 operator delete: void operator delete(void *), 析构方法 pX->~X().

New 的基本使用指南:

想在堆上建立一个对象,应该用new操作符。它既分配内存又为对象调用构造函数。如果仅仅想分配内存,就应该调用operator new 函数;它不会调用构造函数。如果想定制在堆对象被建立时的内存分配过程,你应该写你自己的 operator new函数,然后使用new操作符,new 操作符会调用定制的operator new 。如果想在一块已经获得指针的内存里建立一个对象,应该用 placement new 。 placement new 主要适用于:在对时间要求非常高的应用程序中,因为这些程序分配的时间是确定的;长时间运行而不被打断的程序;以及执行一个垃圾收集器 (garbage collector) 。 

由于 placement new 的特殊性,下面给出其常规使用步骤:

class Task ; //

char * buff = new char[sizeof(Task)]; // 1) 分配内存

Task *ptask = new(buff) Task ;        // 2) 构造对象

ptask->suspend();      // 3) 正常使用对象

ptask->resume();

ptask->~Task();         // 4) 析构对象

delete [] buff;             // 5) 释放内存

      显然, placement new 可以提高效率,但增加了程序的复杂度,需要自行管理对象的生存期。 Placement new 的使用大量存在于 STL 

    New handler

    当new失败时,将抛出异常bad_alloc。如果想改变new失败处理流程,可定制自己的new-handler,并通过set_new_handler()来改变默认行为:

例子1:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
typedef  void  (*PFV)( void );
 
static  char *  safety;
static  PFV    old_handler;
 
void  my_new_handler ()
{
     delete [] safety;
     popup_window ("Dude, you are running low on heap memory.  You
            should, like, close some windows, or something.
            The next time  you run out, we're gonna burn!");
     set_new_handler (old_handler);
     return ;
}
 
int  main ()
{
     safety = new  char [500000];
     old_handler = set_new_handler (&my_new_handler);
     ...
}
例子2:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
// #include <exception>
#include <stdexcept>    // under /usr/include/c++/[G++ VERTION]/stdexcept
 
using  namespace  std;
 
static  new_handler old_new_handler = 0;  // record old new handler
 
void  NewHandler()
{
     /********* Release a lot of memory **********/
 
     if  (old_new_handler)
         old_new_handler();
     else
         throw  bad_alloc();
}
 
int  main( int  argc, char ** argv)
{
     old_new_handler = set_new_handler(&NewHandler);
     /* your progrom */
 
     return  0;
}

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

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

兄弟的公司:立即团

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


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

相关文章
|
5月前
|
C++
【C++】深入解析C/C++内存管理:new与delete的使用及原理(二)
【C++】深入解析C/C++内存管理:new与delete的使用及原理
|
5月前
|
编译器 C++ 开发者
【C++】深入解析C/C++内存管理:new与delete的使用及原理(三)
【C++】深入解析C/C++内存管理:new与delete的使用及原理
119 3
|
2月前
|
C++ 开发者
C++学习之继承
通过继承,C++可以实现代码重用、扩展类的功能并支持多态性。理解继承的类型、重写与重载、多重继承及其相关问题,对于掌握C++面向对象编程至关重要。希望本文能为您的C++学习和开发提供实用的指导。
66 16
|
3月前
|
算法 网络安全 区块链
2023/11/10学习记录-C/C++对称分组加密DES
本文介绍了对称分组加密的常见算法(如DES、3DES、AES和国密SM4)及其应用场景,包括文件和视频加密、比特币私钥加密、消息和配置项加密及SSL通信加密。文章还详细展示了如何使用异或实现一个简易的对称加密算法,并通过示例代码演示了DES算法在ECB和CBC模式下的加密和解密过程,以及如何封装DES实现CBC和ECB的PKCS7Padding分块填充。
76 4
2023/11/10学习记录-C/C++对称分组加密DES
|
5月前
|
编译器 C语言 C++
配置C++的学习环境
【10月更文挑战第18天】如果想要学习C++语言,那就需要配置必要的环境和相关的软件,才可以帮助自己更好的掌握语法知识。 一、本地环境设置 如果您想要设置 C++ 语言环境,您需要确保电脑上有以下两款可用的软件,文本编辑器和 C++ 编译器。 二、文本编辑器 通过编辑器创建的文件通常称为源文件,源文件包含程序源代码。 C++ 程序的源文件通常使用扩展名 .cpp、.cp 或 .c。 在开始编程之前,请确保您有一个文本编辑器,且有足够的经验来编写一个计算机程序,然后把它保存在一个文件中,编译并执行它。 Visual Studio Code:虽然它是一个通用的文本编辑器,但它有很多插
119 6
|
5月前
|
程序员 C语言 C++
C++入门5——C/C++动态内存管理(new与delete)
C++入门5——C/C++动态内存管理(new与delete)
126 1
|
5月前
|
Java 编译器 C++
c++学习,和友元函数
本文讨论了C++中的友元函数、继承规则、运算符重载以及内存管理的重要性,并提到了指针在C++中的强大功能和使用时需要注意的问题。
50 1
|
24天前
|
编译器 C++ 开发者
【C++篇】深度解析类与对象(下)
在上一篇博客中,我们学习了C++的基础类与对象概念,包括类的定义、对象的使用和构造函数的作用。在这一篇,我们将深入探讨C++类的一些重要特性,如构造函数的高级用法、类型转换、static成员、友元、内部类、匿名对象,以及对象拷贝优化等。这些内容可以帮助你更好地理解和应用面向对象编程的核心理念,提升代码的健壮性、灵活性和可维护性。
|
3天前
|
设计模式 安全 C++
【C++进阶】特殊类设计 && 单例模式
通过对特殊类设计和单例模式的深入探讨,我们可以更好地设计和实现复杂的C++程序。特殊类设计提高了代码的安全性和可维护性,而单例模式则确保类的唯一实例性和全局访问性。理解并掌握这些高级设计技巧,对于提升C++编程水平至关重要。
31 16
|
7天前
|
安全 C++
【c++】继承(继承的定义格式、赋值兼容转换、多继承、派生类默认成员函数规则、继承与友元、继承与静态成员)
本文深入探讨了C++中的继承机制,作为面向对象编程(OOP)的核心特性之一。继承通过允许派生类扩展基类的属性和方法,极大促进了代码复用,增强了代码的可维护性和可扩展性。文章详细介绍了继承的基本概念、定义格式、继承方式(public、protected、private)、赋值兼容转换、作用域问题、默认成员函数规则、继承与友元、静态成员、多继承及菱形继承问题,并对比了继承与组合的优缺点。最后总结指出,虽然继承提高了代码灵活性和复用率,但也带来了耦合度高的问题,建议在“has-a”和“is-a”关系同时存在时优先使用组合。
45 6