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
  • 相关阅读:
    37. Sudoku Solver(js)
    36. Valid Sudoku(js)
    35. Search Insert Position(js)
    34. Find First and Last Position of Element in Sorted Array(js)
    33. Search in Rotated Sorted Array(js)
    32. Longest Valid Parentheses(js)
    函数的柯里化
    俞敏洪:我和马云就差了8个字
    vue路由传值params和query的区别
    简述vuex的数据传递流程
  • 原文地址:https://www.cnblogs.com/vanis/p/2941538.html
Copyright © 2011-2022 走看看