C++中的new和delete
来源:互联网 发布:淘宝店铺页头怎么改 编辑:程序博客网 时间:2024/06/04 03:59
C++中的new/delete运算符有两种含义:
1. new/delete operator,内置的运算符(即new和delete这两个keywords),用来分配内存(需要调用2中描述的运算符)并初始化变量/对象(调用构造函数等)。
2. operator new/delete,用来进行内存分配和回收的运算符,只负责内存的分配和回收。
看下面的例子:
class MyClass {…};
MyClass *p = new MyClass; // there should be a default constructor in MyClass
这个例子中的 new是1中描述的运算符。实际上它执行如下3个过程:
1). 调用2中描述的new算符分配内存;
2). 调用构造函数完成对象的创建和初始化(因为需要完成ctor和dtor的自动调用,所以C++新增了new和delete这两个关键字,C中的malloc()和free()是函数,无法完成这样的任务);
3). 返回相应的指针。
2中描述的算符在C++中有3种定义,下面的代码片段摘自new文件(CentOS 5.4, /usr/include/c++/4.1.2/new)。
// plain new/delete
// 带抛出异常的版本
void* operator new(std::size_t) throw (std::bad_alloc);
void* operator new[](std::size_t) throw (std::bad_alloc);
void operator delete(void*) throw();
void operator delete[](void*) throw();
// nothrow new/delete
// 不抛出异常的版本
void* operator new(std::size_t, const std::nothrow_t&) throw();
void* operator new[](std::size_t, const std::nothrow_t&) throw();
void operator delete(void*, const std::nothrow_t&) throw();
void operator delete[](void*, const std::nothrow_t&) throw();
// Default placement versions of operator new.
inline void* operator new(std::size_t, void* __p) throw() { return __p; }
inline void* operator new[](std::size_t, void* __p) throw() { return __p; }
// Default placement versions of operator delete.
inline void operator delete (void*, void*) throw() { }
inline void operator delete[](void*, void*) throw() { }
因为1中描述的new/delete最终会调用2中描述的new/delete,而2中提及的new/delete共有上述3种版本,那么1中提及的new/delete(主要是new)则有3种调用方式。(补充:new operator的3种调用方式用来告诉编译器调用哪个operator new,而delete operator则只有一种调用方式,operator delete的3个版本主要是给编译器使用的,如构造函数抛出异常时调用operator new对应的operator delete来释放内存。)
// 1. plain new
try
{
char *p = new char[10000000];
…
delete []p;
}
catch (const std::bad_alloc &ex)
{
cout << ex.what() << endl;
}
// 2. nothrow new
char *p = new(nothrow) char[10000000];
if (NULL == p) cout << “allocation failed!” << endl;
…
delete []p;
// 3. placement new
char *p = new(nothrow) char[4];
if (NULL == p)
{
cout << “allocation failed!” << endl;
exit(-1);
}
…
long *q = new(p) long(1000);
…
delete []p;
为了证明1中提及的new/delete的工作方式,来看下面的演示代码:
#include <iostream>
using namespace std;
class Demo
{
public:
Demo() : __x(0)
{
static int counter = 0;
cout << "default ctor is called: " << ++counter << endl;
}
~Demo()
{
static int counter = 0;
cout << "dtor is called: " << ++counter << endl;
}
// 这里我们对global作用域中带异常抛出版本的new/delete进行重载
static void* operator new(std::size_t) throw (std::bad_alloc);
static void* operator new[](std::size_t) throw (std::bad_alloc);
static void operator delete(void*) throw();
static void operator delete[](void*) throw();
private:
int __x;
};
void* Demo::operator new(std::size_t size) throw (std::bad_alloc)
{
cout << "operator new is called, size = " << size << endl;
// 此处我们直接调用global作用域中的new
return ::operator new(size);
}
void* Demo::operator new[](std::size_t size) throw (std::bad_alloc)
{
cout << "operator new[] is called, size = " << size << endl;
// 此处我们直接调用global作用域中的new[]
return ::operator new[](size);
}
void Demo::operator delete(void *p) throw()
{
cout << "operator delete is called" << endl;
// 此处我们直接调用global作用域中的delete
::operator delete(p);
}
void Demo::operator delete[](void *p) throw()
{
cout << "operator delete[] is called" << endl;
// 此处我们直接调用global作用域中的delete[]
::operator delete[](p);
}
int main(void)
{
try
{
Demo *p = new Demo;
delete p;
Demo *pa = new Demo[3];
delete []pa;
}
catch(const std::bad_alloc &ex)
{
cout << ex.what() << endl;
}
return 0;
}
程序的输出结果如下(CentOS 5.4, g++ 4.1.2):
operator new is called, size = 4
default ctor is called: 1
dtor is called: 1
operator delete is called
operator new[] is called, size = 16 (猜猜这里为什么是16)
default ctor is called: 2
default ctor is called: 3
default ctor is called: 4
dtor is called: 2
dtor is called: 3
dtor is called: 4
operator delete[] is called
从上面的输出可以看出当new一个对象的时候,重载的operator new会先被调用,然后是构造函数;delete一个对象时,则先调用析构函数,然后调用重载的operator delete。
- C++:new和delete
- new和delete【C++】
- C++ 中的 new/delete 和 new[]/delete[]
- C++中的new/delete和new[]/delete[]
- C++ 中的 new/delete 和 new[]/delete[]
- C++中的new delete和new[] delete []
- C++中的new/delete和new[]/delete[]
- C++ 中的 new/delete 和 new[]/delete[]
- C++中的new和delete
- C++中的new和delete
- C++中的new和delete
- C++中的new和delete
- C++中的new和delete
- C++中的new和delete
- Qt中的delete和new
- c++中的new和delete
- C++中的new和delete
- C++new和delete重载
- 需求:需要在许多子窗体中关闭/退出整个程序(WPF)
- SqlDataAdapter 应用。
- automake,autoconf使用详解
- [转]浅析C++中虚函数的调用及对象的内部布局(利用汇编深刻理解C++虚函数底层实现机制)
- js的对象
- C++中的new和delete
- 今天第一次进入
- 我要关注
- google炸弹,你玩过了么?
- 按钮加上图片
- 禁用U盘
- Android反编译工具Apktool使用
- SQL Server 解决Can't start manual transaction mode问题
- V4l2 Capture Sequence