zoukankan      html  css  js  c++  java
  • 重载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的话才会被覆盖

    本篇博客为原创作品,个人转载或引用时请保留本人的署名及博客网址,商业转载请事先联系。我的博客地址是:http://www.cnblogs.com/vanis/ , 我的hotmail.com邮箱是vanishs
  • 相关阅读:
    LeetCode-46. Permutations
    LeetCode-40. Combination Sum II
    LeetCode-39. Combination Sum
    剑指offer-数组中的逆序对
    LeetCode-295. Find Median from Data Stream
    LeetCode-268. Missing Number
    LeetCode-515. Find Largest Value in Each Tree Row
    GIS技术在采矿与勘探中的应用
    JavaScript 跨域总结与解决办法giserdqy.com
    JavaScript 跨域总结与解决办法giserdqy.com
  • 原文地址:https://www.cnblogs.com/vanis/p/2941538.html
Copyright © 2011-2022 走看看