重载delete(operator delete)

最近做了一个线程类,发现需要用用到重载delete,所以就此研究了一下

先来看看代码

struct thread
{
    thread()
    {
        printf("thread() 1\n");
        std::thread st(
            [](thread *self)
            {
                int i=0;
                while(1)
                {
                    std::chrono::milliseconds dura(1000);
                    std::this_thread::sleep_for(dura);
                    if(self->exit)
                    {
                        printf("thread run %d\n",i);
                        return;
                    }
                    i++;
                    printf("thread run %d\n",i);
                }
            }
            ,
            this
        );
        st.detach();

    }
    virtual ~thread()
    {
        printf("~thread()\n");
    }

    int exit=0;
};


int main()
{
    thread *p = new thread;


    //test(10);
    printf("---------end----------\n");
    getch();
    return 0;
}

这里使用了c++11标准,不熟悉的同学就当作伪代码来看

class thread是一个线程类。new thread 的时候就建立好了线程

好了,线程建立起来了,你可以把exit成员赋值为1的时候就会线程退出

你可以在类里面加入一个叫做close()这样的方法,把exit设置为1 然后在线程return之前delete self就可以了

 

但是这样违背了new delete配对的原则,用new出来线程,close线程太不合适

最好是new 线程,delete线程

可是问题就来了,delete之后 exit已经不存在,线程就会访问非法内存地址导致程序崩溃

这是一个矛盾的问题,如果能解决delete的时候设置exit=1却不销毁掉内存就能解决该问题了

c++已经准备好这样的功能给你了

 

c++ 对delete 一个对象的时候 首先会调用析构函数,你可以把析构函数看成一个特殊的函数,在delete对象的时候会被调用(其实就是)

紧接着 c++会调用delete 销毁掉内存,所以你现在只需要重载该类的delete就可以了,重载delete里面不去做任何销毁内存的事情,这样 内存得以保留

在类里面修改~thread()和添加一个重载delete:

    virtual ~thread()
    {
        printf("~thread()\n");
        exit=1;
    }

    void operator delete(void *self)
    {
        //nothing todo
    }

 

然后再线程return之前调用 delete (void*)self;

这样 在你delete p;的时候,首先exit被复制1,然后因为重载了类的delete 所以内存没有被销毁掉,所以程序依然正常运行,当线程遇到exit=1的时候,程序在退出前释放掉内存空间

这样就解决了new 和 delete 匹配问题

为什么 在线程return之前调用的是delete (void*)self;呢?原因很简单,你现在要做的事情是释放内容,而不是调用类的析构函数(现在析构函数也重载了delete不去干任何事了)

还有,经过测试delete会被继承到派生类,如果派生类重新重载delete的话才会被覆盖

 

转载于:https://www.cnblogs.com/vanis/archive/2013/03/03/2941538.html

C++中,可以重载new和delete运算符以定制动态内存管理的行为。重载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运算符,以确保内存的正确释放。 可以根据需要重载其他版本的new和delete运算符,例如带有额外参数的new和delete运算符,数组形式的new和delete运算符等。重载这些运算符时需要遵循一定的规则和约定,确保正确性和可靠性。 值得注意的是,C++11引入了更加灵活和安全的内存管理方式,例如智能指针(如std::shared_ptr和std::unique_ptr)和RAII(资源获取即初始化)等,这些方式可以减少手动管理内存的复杂性和错误。因此,在使用new和delete运算符进行内存管理之前,建议先考虑这些更高级的内存管理工具。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值