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属性,才可以在外部被调用。

  • 0
    点赞
  • 3
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
C++中,可以重载newdelete运算符以定制动态内存管理的行为。重载new运算符可以用于自定义内存分配的方式,而重载delete运算符可以用于自定义内存释放的方式。 重载new运算符的一种常见方式是定义一个全局new运算符函数,并使用该函数来执行内存分配。例如: ```cpp void* operator new(size_t size) { // 自定义内存分配逻辑 void* ptr = malloc(size); // 检查分配是否成功 if (ptr == nullptr) { throw std::bad_alloc(); } return ptr; } ``` 重载delete运算符的一种常见方式是定义一个全局delete运算符函数,并使用该函数来执行内存释放。例如: ```cpp void operator delete(void* ptr) noexcept { // 自定义内存释放逻辑 free(ptr); } ``` 需要注意的是,如果重载new运算符,通常也需要相应地重载delete运算符,以确保内存的正确释放。 可以根据需要重载其他版本的newdelete运算符,例如带有额外参数的newdelete运算符,数组形式的newdelete运算符等。重载这些运算符时需要遵循一定的规则和约定,确保正确性和可靠性。 值得注意的是,C++11引入了更加灵活和安全的内存管理方式,例如智能指针(如std::shared_ptr和std::unique_ptr)和RAII(资源获取即初始化)等,这些方式可以减少手动管理内存的复杂性和错误。因此,在使用newdelete运算符进行内存管理之前,建议先考虑这些更高级的内存管理工具。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值