zoukankan      html  css  js  c++  java
  • 第9课

    内存泄漏

      -动态申请堆空间,用完后不归还

      -c++语言中没有垃圾回收机制

      -指针无法控制所指堆空间的生命周期

    代码练兵场:

    #ifndef SMARTPOINTER_H
    #define SMARTPOINTER_H
    
    namespace DTLib
    {
        template<typename T>
        class SmartPointer
        {
        public:
            SmartPointer(T *p=nullptr)
            {
                m_pointer=p;
            }
            SmartPointer(const SmartPointer<T>& obj)
            {
                m_pointer=obj.m_pointer;
                const_cast<SmartPointer<T>&>(obj).m_pointer=nullptr;
            }
            SmartPointer<T>& operator =(const SmartPointer<T>& obj)
            {
                if(this!=&obj)
                {
                    delete m_pointer;//一定要先释放之前指向的空间,虽然可能delete一个null指针让我们觉得有点怪异,比如默认初始化sp,然后把p赋值给sp,此时delete的是null,但是程序是没有害处的、要是想要完全合乎new和delete配对,可以在这个delete前加一个if判断,如果非NULL,就delete
                    m_pointer=obj.m_pointer;
                    const_cast<SmartPointer<T>&>(obj).m_pointer=nullptr;
                }
                return *this;
            }
            T *operator->()
            {
                return m_pointer;
            }
            T &operator*()
            {
                return *m_pointer;
            }
            bool isNull()
            {
                return (m_pointer==nullptr);
            }
            T *get()
            {
                return m_pointer;
            }
            ~SmartPointer()
            {
                delete m_pointer;
            }
        protected:
            T *m_pointer;
        };
    }
    #endif // SMARTPOINTER_H

    main.cpp:

    #include <iostream>
    #include "smartpointer.h"
    using namespace std;
    using namespace DTLib;
    
    class Test
    {
    public:
        Test()
        {
            cout<<" Test()"<<endl;
        }
        ~Test()
        {
            cout<<" ~Test()"<<endl;
        }
    };
    int main()
    {
       SmartPointer<Test> p= new Test();
       SmartPointer<Test> sp=p;
      // sp=p;
       //sp++;
       cout<<p.isNull()<<endl;
       cout<<sp.isNull()<<endl;
        return 0;
    }

    输出:

     代码知识点解释:

     

    const_cast<SmartPointer<T>&>(obj).m_pointer=nullptr;,在拷贝构造函数中,obj是const的,内容不允许修改,但是我们的智能指针设计需求第二步,开辟的堆空间,只能有一个指针标识,所以我想去掉obj类中的指针成员的指向,使用强制类型转化,去掉obj类的const属性,注意obj是我们要去const化的,而不是obj.m_pointer。同样的道理,我们需要重载赋值运算符,在不是自赋值的情况下,满足重载赋值运算符的if条件(针对上面的代码而言),释放this的m_pointer指向的内存,把obj的指针赋值给this的m_pointer,再把obj的m_pointer指针置成null,这样还是为了只给一个指针标识。然后重载了->和解引用*操作符。在main.cpp中,我们创建了一个Test类,用智能指针指向这个new出来的类,再把p指针用了初始化sp(将调用拷贝构造函数),此时,首先打印Test的无参构造函数,然后p初始化了sp,故p的m_pointer应该被置成了null,所以isNull函数返回1,但是sp此时接管Test类的内存,所以sp的isNull返回0,非空。最后Test类析构,智能指针指向的内存也会因为调用了自己的析构函数释放内存。在我们实现的智能指针中,是不运行执行指针和比较的,执行++这种操作是没有定义的,符合之前我们提到的智能指针三个要求。c++11中,建议用nullptr代替NULL。

     NOTE:

    智能指针用来指向堆空间中的单个对象或者变量。

  • 相关阅读:
    130517Dev GridControl建立多行复杂表头(Banded View)时,统计列与对应列无法对齐的解决办法
    C&C++标准库
    Linux操作系统下的多线程编程详细解析
    Ubuntu12.04用户以root身份登录
    ubuntu永久修改主机名
    linux信号 linux signal
    淘宝api 登录验证
    淘宝开店 防骗 易赛加款诈骗|冲q币恶意差评
    面试..
    test
  • 原文地址:https://www.cnblogs.com/yangguang-it/p/7195819.html
Copyright © 2011-2022 走看看