9. new 和 delete 运算符重载

C++ 语言允许重载 newdelete 运算符,通过重载这些运算符,可以实现内存分配的自主控制。

newdelete 运算符重载的方法

// 动态分配单个对象
void *operator new(size_t sz) { ... }
// 释放单个对象
void operator delete(void *ptr) noexcept { ... }

// 动态分配对象数组
void *operator new[](size_t sz) { ... }
// 释放对象数组
void operator delete[](void *ptr, size_t sz) noexcept { ... }

关于 noexcept 关键字,后面才讲。

示例

重载 newdelete 运算符,将所有使用 new 动态创建的对象头使用同一块内存(对象内存共享)。

// filename: op_new_delete.cpp
#include <iostream>

using namespace std;

class Complex {
    public:
        Complex(double r=0, double i=0): real(r), image(i){}
    private:
        double real;
        double image;

    // 友元全局函数声明
    friend ostream & operator << (ostream & o, const Complex & c);
};

ostream & operator << (ostream & o, const Complex & c) {
    o << "(" << c.real << "+" << c.image << "i)";
    return o;
}

// 用于存放动态创建对象的缓冲区
static char mem_buf[4096];

// 重载 new 和 delete 运算符
void * operator new(size_t sz) {
    cout << "operator new 被调用, sz:" << sz << endl;
    return mem_buf;
}
void operator delete(void *ptr) noexcept {
    cout << "operator delete: ptr:" << ptr << endl; 
}

// 重载 new[] 和 delete[] 运算符
void * operator new[](size_t sz) {
    cout << "operator new[] 被调用, sz:" << sz << endl;
    return mem_buf;
}
void operator delete[](void *ptr,size_t sz) noexcept {
    cout << "operator delete[]: ptr:" << ptr << "sz:" << sz << endl;
}
int main(int argc, char * argv[]) {
    Complex *pc1, *pc2, *pc3;
    pc1 = new Complex(1, 2);

    cout << "mem_buf:" << &mem_buf << endl;
    cout << "pc1:" << pc1 << " *pc1:" << *pc1 << endl;
    cout << "动态创建 Complex(3, 4);" << endl;
    pc2 = new Complex(3, 4);
    cout << "pc1:" << pc1 << " *pc1:" << *pc1 << endl;
    cout << "pc2:" << pc2 << " *pc2:" << *pc2 << endl;
    cout << "动态创建 new Complex[2];" << endl;
    pc3 = new Complex[2]{Complex(5, 6), Complex(7, 8)};
    cout << "pc1:" << pc1 << " *pc1:" << *pc1 << endl;
    cout << "pc2:" << pc2 << " *pc2:" << *pc2 << endl;
    cout << "pc3:" << pc3 << "pc3[0]:" << pc3[0] << endl;
    delete pc1;
    delete pc2;
    delete[] pc3;

    return 0;
}

编译和运行结果如下:

weimz@mzstudio:~$ g++ -o op_new_delete op_new_delete.cpp
weimz@mzstudio:~$ ./op_new_delete 
operator new 被调用, sz:16
mem_buf:0x58ffb9499160
pc1:0x58ffb9499160 *pc1:(1+2i)
动态创建 Complex(3, 4);
operator new 被调用, sz:16
pc1:0x58ffb9499160 *pc1:(3+4i)
pc2:0x58ffb9499160 *pc2:(3+4i)
动态创建 new Complex[2];
operator new[] 被调用, sz:32
pc1:0x58ffb9499160 *pc1:(5+6i)
pc2:0x58ffb9499160 *pc2:(5+6i)
pc3:0x58ffb9499160pc3[0]:(5+6i)
operator delete: ptr:0x58ffb9499160
operator delete: ptr:0x58ffb9499160
operator delete: ptr:0x58ffb9499160