C++ new / delete 重载

1. new 与delete的如何工作

当使用new表达式的时候

string * sp = new string("initialized");

的时候,实际发生了三个步骤:

  1. 该表达式调用名为operator new的标准库函数分配足够大的原始的未类型初始化的内存。以保存指定类型的一个对象。
  2. 运行该类型的一个构造函数,用指定初始化式构造对象。
  3. 返回指向新分配并构造的对象的指针

当使用delete表达式的

delete sp;

删除动态分配的对象的时候,发生两个步骤:

  1. 对指向的对象运行适当的析构函数。
  2. 调用名为operator delete的标准库函数释放该对象所有的内存。

通过分析上面的工作过程,可以看到new和delete实际并不等同于operator new() 和operator delete(), new和delete做的事情要更多,实际上我们不能重定义new 和delete表达式的行为。
operator new 和operator delete的命名容易让人误解,与其他operator函数(如operator=)不同,这两个函数并没有重载new和delete。所以标题所谓的new/delete重载并不准确。如果要进行重载实际上重载的是operator new和operator delete函数。

2. operator new 和operator delete接口

operator new和 operator delete 函数有两个重载版本每个版本支持相关的new表达式和delete表达式:

void * operator new(size_t);
void * operator new[](size_t);

void * operator delete(void*);
void * operator delete[](void*);

3.重载operator new和 operator delete

class Test
{
    
    
public:
    void* operator new(size_t size)
    {
    
    
        cout << " use operator new... " << endl;
        return malloc(size);
    }

    void operator delete(void* var)
    {
    
    
        cout << "use operator delete ..., var:" << var << endl;
        free(var);
    }
};
int main()
{
    
    
    Test* m = new Test;

    cout << "m: " << m << std::endl;
    delete m;
}

operator new返回值必须是void*。第一个参数必须是size_t,还可加其它参数。
operator new重载可以放在全局中,也可以放到类内部。当编译器发现有new关键字,就会现在类和其基类中寻找operator new,找不到就在全局中找,再找不到就用默认的。
operator delete 返回类型必须是void,可以接受单个void*类型的形参,也可以定义接受两个形参,该指针可以为空指针。
这些函数隐式的为静态函数,不必显示的将他们声明为static。如果重载的是成员函数,责operator new和operator delete 函数必须是静态的。因为他们要么在构造对象之前使用(operator new),要么在撤销对象之后使用(operator delete)。因此这些函数没有成员数据可操纵,向任意其他静态函数一样,也只能访问静态成员。
基于同样原因,这些函数必须是public的,因为调用的时候都是在对象外调用,必须public属性,才可以在外部被调用。

猜你喜欢

转载自blog.csdn.net/yangcunbiao/article/details/131147920
今日推荐