[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  ,如需转载请自行联系原作者

相关文章
|
4天前
|
存储 编译器 C语言
c++的学习之路:5、类和对象(1)
c++的学习之路:5、类和对象(1)
19 0
|
18天前
|
存储 C++ 容器
C++STL(标准模板库)处理学习应用案例
【4月更文挑战第8天】使用C++ STL,通过`std:vector`存储整数数组 `{5, 3, 1, 4, 2}`,然后利用`std::sort`进行排序,输出排序后序列:`std:vector<int> numbers; numbers = {5, 3, 1, 4, 2}; std:sort(numbers.begin(), numbers.end()); for (int number : numbers) { std::cout << number << " "; }`
19 2
|
29天前
|
存储 安全 编译器
C++学习过程中的一些值得注意的小点(1)
C++学习过程中的一些值得注意的小点(1)
|
30天前
|
存储 算法 数据库
【C++ 软件设计思路】学习C++中如何生成唯一标识符:从UUID到自定义规则
【C++ 软件设计思路】学习C++中如何生成唯一标识符:从UUID到自定义规则
106 0
|
4天前
|
C++
c++的学习之路:7、类和对象(3)
c++的学习之路:7、类和对象(3)
19 0
|
4天前
|
C语言 C++
c++的学习之路:4、入门(3)
c++的学习之路:4、入门(3)
18 0
|
4天前
|
编译器 C++
c++的学习之路:23、多态(2)
c++的学习之路:23、多态(2)
17 0
|
18天前
|
程序员 C++
C++语言模板学习应用案例
C++模板实现通用代码,以适应多种数据类型。示例展示了一个计算两数之和的模板函数`add&lt;T&gt;`,可处理整数和浮点数。在`main`函数中,展示了对`add`模板的调用,分别计算整数和浮点数的和,输出结果。
12 2
|
30天前
|
存储 Linux C语言
【C++练级之路】【Lv.5】动态内存管理(都2023年了,不会有人还不知道new吧?)
【C++练级之路】【Lv.5】动态内存管理(都2023年了,不会有人还不知道new吧?)
|
30天前
|
算法 安全 编译器
【C++ 17 新特性 折叠表达式 fold expressions】理解学习 C++ 17 折叠表达式 的用法
【C++ 17 新特性 折叠表达式 fold expressions】理解学习 C++ 17 折叠表达式 的用法
23 1