曲径通幽论坛

 找回密码
 立即注册
搜索
查看: 3612|回复: 0
打印 上一主题 下一主题

重载 new 和 delete

[复制链接]

4917

主题

5879

帖子

3万

积分

GROAD

曲径通幽,安觅芳踪。

Rank: 6Rank: 6

积分
34382
跳转到指定楼层
楼主
发表于 2011-11-21 10:27:41 | 只看该作者 回帖奖励 |倒序浏览 |阅读模式
new 和 delete 是运算符,它们都可以被重载。

重载 new 和 delete 的函数框架如下:
[C++] 纯文本查看 复制代码
//为一个对象分配内存
void *operator new(size_t size)
{
   /*执行分配操作。在失败时抛出 bad_alloc类型异常。构造函数自动被调用*/
   return pointer_to_memory;
}


//释放对象的内存
void operator delete(void *p)
{
   /*释放由 p 指向的内存,析构函数自动被调用*/
}

size_t 是一个可移植的预定义数据类型,一般被定义为 unsigned int ,它可以包含最大可分配的单块内存的大小。
size包含为对象分配的字节数。
重载运算符函数 new 必须返回一个指向它所分配的内存的指针,或者在发生错误时抛出一个 bad_alloc 类型异常。当位一个对象分配内存时,构造函数被自动调用。
delete 函数负责将前面分配的内存释放回系统中。当对象被删除时,对象的析构函数被自动调用。

要为对象数组分配或者释放内存,必须使用下面的 new 和 delete 形式
[C++] 纯文本查看 复制代码
//为对象数组分配内存
void *operator new[] (size_t size)
{
  /*执行分配操作,失败时抛出 bad_alloc 类型异常。数组中每个对象的构造函数被自动调用*/
}


//删除对象数组
void operator delete[] (void *p)
{
   /*释放由 p 指向的内存,数组中每个对象的析构函数都被自动调用*/
}


测试代码
[C++] 纯文本查看 复制代码
#include <iostream>
#include <new>
#include <cstdlib>
using namespace std;


class three_d {
        int x, y, z;    //三维坐标
public:
        three_d() {
                x = y = z = 0;
                cout << "Constructing 0, 0, 0\n";
        }


        three_d(int i, int j, int k) {
                x = i; y = j; z = k;
                cout << "Constructing " << i << ", ";
                cout << j << ", " << k;
                cout << '\n';
        }


        ~three_d() { cout << "Destructing\n"; }


        void *operator new(size_t size);
        void *operator new[](size_t size);
        void operator delete(void *p);
        void operator delete[](void *p);
        void show();
};


//重载tree_d的运算符new
void *three_d::operator new(size_t size)
{
        void *p;
        cout << "Allocating three_d object.\n";
        p = malloc(size);


        //在内存分配失败时抛出异常
        if(!p) {
                bad_alloc ba;
                throw ba;
        }
        return p;
}


//重载 three_d 数组的运算符new
void *three_d::operator new[](size_t size)
{
        void *p;
        cout << "Allocating array of three_d objects.\n";




        //在内存分配失败时抛出异常
        p = malloc(size);
        if (!p) {
                bad_alloc ba;
                throw ba;
        }
        return p;
}


//重载 three_d 的运算符delete
void three_d::operator delete(void *p)
{
        cout << "Deleting three_d object.\n";
        free(p);
}


//重载 three_d 数组的运算符delete
void three_d::operator delete[](void *p)
{
        cout << "Deleting array of three_d objects.\n";
        free(p);
}


//输出x,x,z的坐标值
void three_d::show()
{
        cout << x << " ";
        cout << y << " ";
        cout << z << endl;
}


int main()
{
        three_d *p1, *p2;
        try {
                p1 = new three_d[3];    //为对象数组分配内存
                p2 = new three_d(5, 6, 7);      //为单个对象分配内存
        }
        catch (bad_alloc ba) {
                cout << "Allocation error.\n";
                return 1;
        }


        p1[1].show();
        p2->show();


        delete [] p1;   //删除数组
        delete p2;      //删除对象


        return 0;
}

运行输出:
./reload_newdel
Allocating array of three_d objects.
Constructing 0, 0, 0
Constructing 0, 0, 0
Constructing 0, 0, 0
Allocating three_d object.
Constructing 5, 6, 7
0 0 0
5 6 7
Destructing
Destructing
Destructing
Deleting array of three_d objects.
Destructing
Deleting three_d object.
在输出中,前面 3 条 Constructing 是在为对象数组分配内存时输出的。数组中共包含了 3 个 three_d 类型对象,在为数组分配内存时,数组中的每个成员的构造函数将被自动调用。最后一跳
Constructing 5, 6, 7 信息是为创建单独一个 three_d 类型对象时输出的。同理,前面 3 条提示信息 Destrucing 是在删除数组时输出的,析构函数也都被自动调用;而最后一条 Destrucing 由删除单个对象时输出。

注意:new 和 delete 这两个运算符的重载是与类相关的。如果对其他类型数据使用这些运算符,那么使用默认的 new 和 delete,比如在 main() 中加入 int *f = new int; 这条语句,那么默认的的运算符 new 将被执行,而不是使用上面的重载形式。

最后一点,也可以在全局作用域内重载 new 和 delete 。定义全局运算符的方法是将 operator 函数声明在所有类的定义之外。在这种情况下,C++ 中默认的运算符 new 和 delete 都将被忽略,而一致都采用全局重载形式。当然,和局部变量的原理一样,如果你同时在某个类中也定义了它自己的重载 new 和 delete,那么在为该类分配对象内存和释放对象内存时,使用的是类中定义的重载 new 和  delete。而对于其他类,使用的仍然是全局作用域中的 new 和 delete  。
您需要登录后才可以回帖 登录 | 立即注册

本版积分规则

小黑屋|手机版|Archiver|曲径通幽 ( 琼ICP备11001422号-1|公安备案:46900502000207 )

GMT+8, 2024-5-18 01:56 , Processed in 0.078356 second(s), 24 queries .

Powered by Discuz! X3.2

© 2001-2013 Comsenz Inc.

快速回复 返回顶部 返回列表