zoukankan      html  css  js  c++  java
  • C++ smart pointer智能指针

      在C++中,程序员可以直接操作内存,给编程增加了不少的灵活性。但是灵活性是有代价的,程序员必须负责自己负责释放自己申请的内存,否则就会出现内存泄露。智能指针就是为了解决这个问题而存在的。它和其他指针没有本质的区别,主要的目的就是为了避免悬挂指针、内存泄露的问题。在这里,我使用对象的应用计数做了一个smart pointer,当一个对象还有引用的时候,就不执行释放内存的操作,当引用计数为0时,就执行内存释放操作,并且将指针重置为NULL。

    代码如下:

    #include <iostream>
    #include <malloc.h>
    
    /*
    
     desc:   A smart pointer to automatic alloc and dellocat memories.
     author: justinzhang(uestczhangchao@gmail.com).
     time: 2015-1-22 09:44:24
    
    */
    
    template <class T>
    class smartPtr {
    
    public:
      smartPtr() {
        ptr = NULL;
        refCnt = (unsigned *) malloc(sizeof(unsigned));
      }
    
      smartPtr( T * pt) {
    
    
        this->ptr = pt;
        refCnt = (unsigned *) malloc(sizeof(unsigned));
        std::cout << "Enter constructor, refCnt is "<< *refCnt << std::endl;
        *refCnt = 1;
        
        std::cout << "Leave constructor, refCnt is " << *refCnt << std::endl;
        
      }
    
      smartPtr(smartPtr<T> &copy) {
    
       
        ptr = copy.ptr;
        
        refCnt = copy.refCnt;
        std::cout << "Enter copy constructor, refCnt is " << *refCnt << std::endl;
        
        ++*refCnt;
        
        std::cout << "Leave copy constructor, refCnt is "<< *refCnt << std::endl;
    
      }
      
      smartPtr<T> & operator=(smartPtr<T> &copy) {
        
        std::cout << "Enter operator=, refCnt is "<< *copy.refCnt << std::endl;
        
        if(this != &copy) {
          ptr = copy.ptr;
          refCnt = copy.refCnt;
          ++*refCnt;
        }
        std::cout << "Leave operator=, refCnt is " << *refCnt << std::endl;
        return *this;
    
      }
      
      ~smartPtr() {
      
        std::cout << "Enter destructor, refCnt is " << *refCnt << std::endl;
    
        --*refCnt;
    
        if(*refCnt == 0 ) {
          std::cout << "In destructor, refCnt is 0 , this pointer will be freed." << std::endl;
      
          if( NULL != ptr ) {
    
        delete ptr;
            ptr = NULL;
    
          }
    
          if(NULL != refCnt ) {
        free(refCnt);
        refCnt = NULL;
          }
    
    
        } else {
    
          std::cout << "Leave destructor, refCnt is " << *refCnt << std::endl;
        }
    
      }
    
      T getValue() {
    
        return *ptr;
      }
    
    protected:
      T * ptr;
      unsigned *refCnt;
    
    };
    
    
    int main() {
    
      int * p = new int[2];
    
      smartPtr<int > intSmart(p) ; 
      smartPtr<int> copySmart(intSmart); // copy constructor will be called.
      smartPtr<int> operatorSmart = intSmart ; // Here the copy consturctor will be called, not the assignment operator.
      operatorSmart = intSmart; // Here the assignment operator will  be called.
      
      return 0;
    
    }

    运行结果如下:

    image

    image

  • 相关阅读:
    OOAD基本概念
    WEB开发中常用的正则表达式
    一像素的恩怨情仇!程序猿与设计狮之间的那些事儿
    技术负责人的三种角色
    Ping命令详解
    zip命令的用法
    U盘装系统系列三—-ghost系统安装教程
    U盘装系统系列二—-如何设置U盘启动
    U盘装系统系列一—-安装老毛桃U盘启动制作工具
    Vi命令详解
  • 原文地址:https://www.cnblogs.com/justinzhang/p/4240845.html
Copyright © 2011-2022 走看看