Smart pointer / cast

Smart Pointers

1 Why use a smart pointer ------ prevent memory leaks

What is a smart pointer?

Thought is a smart pointer:
RAII: Life cycle using the object control program resource
advantages: 1 no explicit release of resources
2 with end release resources object lifecycle

Smart pointers Category:

std::auto_ptr    
std::unique_ptr
std::shared_ptr

1 std :: auto_ptr

The smart pointer has its drawbacks
when the object copy occurs, or the assignment, he will be suspended the former (ie, freed a former resources).

#include <iostream>

using namespace std;

class Date
{
  public:
    Date(int year =1900, int month =1, int day =1 )
      :year_(year)
      ,month_(month)
      ,day_(day)
      { }
      

    int year_;
    int month_ ;
    int day_;
};

template <class T>
class Auto_ptr
{
  public:
    Auto_ptr( T* ptr = NULL)
    :ptr_(ptr)
    {}



    //auto_ptr :: 1 拷贝之后就会发生悬空,即被拷贝的对象内容消失,转移到了靠背后的对象中
    Auto_ptr( Auto_ptr<T>& prev)
      :ptr_(prev.ptr_)
    {
      prev.ptr_ = NULL;
    }
    ~Auto_ptr()
    {
      if( ptr_ )
        delete ptr_;
    }

    //auto_ptr  2  被赋值之后发生悬空,前面的对象悬空 ,即 this = tmp ;   tmp 悬空   a  = 2;   原有2中资源悬空
    


    Auto_ptr<T>& operator =(Auto_ptr<T>& tmp) 
    {
      // 检查是否自己给自己赋值
      if(this == &tmp)
      {
        return *this;
      }
      else 
      {
          if(! ptr_)
          {
            delete ptr_;//防止内存泄漏
          }
          
          //转移tmp 的资源到 this 中去
          ptr_ = tmp.ptr_;
          tmp.ptr_ = NULL;   //悬空  赋值者的资源
          return *this;//return *ptr_;
      }
  
    }

    T& operator *()
    {
      return * ptr_;
    }

    T* operator ->()
    {
      return ptr_;
    }


  private:
    T* ptr_;
};


int main()
{
   Auto_ptr<Date> a(new Date);
   Auto_ptr<Date> copy(a);


   //预期 下面两种方式都会发生错误
  // cout<<a->year_<<endl;
    a->year_  = 2018;
   return 0;
}

2std::unique_ptr

unique_ptr unique pointer,
since unique, of course, can not be copied, can not be assigned to copy, then we will constructors and copy constructors privatization, c ++ 11 = delete the function behind privatization

#include <iostream>


using namespace std;

//unique_ptr 独一无二的只能指针,简单粗暴 ,防止拷贝,防止赋值

class Date
{
  public:
    Date(int year , int month, int day)
    :year_(year)
    ,month_(month)
    ,day_(day) 
  {}

  
    int year_;
    int month_;
    int day_;
};

template <class T> 
class Unique_ptr
{

  public:
    Unique_ptr(T* a = NULL)
    :a_(a)
    {}
    
    ~Unique_ptr()
    {
      if(a_)
        delete a_;
    }

    T& operator*()
    {
      return *a_;
    }

    T* operator->()
    {
      return a_;
    }
    
  private:
    //防止拷贝 和 赋值 ,我们将其定义为私有成员函数,并且只做声明,不实现
    Unique_ptr(const Unique_ptr<T>& source);
    Unique_ptr& operator = (Unique_ptr<T>& target);
    
    //c++11  新玩法 ,在 函数后面添加  = delete
    T* a_;
};

int main()
{

  return 0;
}

3 std::shared_ptr

shared_ptr uses the principle of reference counting,
similar to the copy before the solution principle, when the reference counter is greater than 0, i.e., the use of copy or copying assignment reference count ++;
due ++ operations are non-atomic, so to ensure thread safety, we lock.

#include <iostream>
#include <thread>
#include <mutex>
using namespace std;


//共享指针 ,原理 采用 浅拷贝 + 引用计数的思想

template <class T>
class Shared_ptr
{
  public:
    Shared_ptr(T* ptr = nullptr)
    :ptr_(ptr)
    ,pMutex_(new mutex)
    ,pCount_(new int(1))
  {}
    
    ~Shared_ptr()
    {
      Relese();
    }

    Shared_ptr(const Shared_ptr<T>& p)
      :ptr_(p.ptr_)
       ,pMutex_(p.pMutex_)
       ,pCount_(p.pCount_)
    {
          AddpCount();//引用计数
    }
    
    Shared_ptr& operator = (Shared_ptr<T>& sp)
    {
        if(&sp  !=  this )//防止给自己赋值
        {
            delete this->ptr_ ;//先释放自己的资源防止内存泄漏

          //标注资源位置
            this->ptr_ = sp.ptr_;
            this->pCount_ = sp.pCount_;
            this->pMutex_ = sp.pMutex_;

            AddpCount();
        }
        return *this;
    }
    

    int Get()
    {
      return *pCount_;
    }
    
    T& operator *(){return *ptr_; }
    T* operator ->(){return ptr_; }



  private:
  void AddpCount()
 {
   pMutex_->lock();
   ++(*pCount_);//这里的引用计数参数必须是指针类型,  因为我们只保留一份数据,传值的话就保留了多份数据,不符合引用计数的思想
   pMutex_->unlock();
 }


  void Relese()
 {
   bool delete_falg = false;
   pMutex_->lock();
   --*pCount_;
   if(*pCount_ == 0)
     delete_falg = true;

   pMutex_->unlock();
  
  if(delete_falg == true)
  {
      delete pCount_;
      delete pMutex_;
      delete ptr_;
  }
 }

    T* ptr_;
    mutex* pMutex_;
    //这里的引用计数参数必须是指针类型,  因为我们只保留一份数据,传值的话就保留了多份对象,不符合引用计数的思想
    int* pCount_;
};

std :: shared_ptr circular reference problem:

struct ListNode
{
//什么类型的对象,就需要什么类型的节点类型
shared_ptr<ListNode> prev_;//智能指针
shared_ptr<ListNode> next_;//智能指针
}//即 一个ListNode 具有两个智能指针,
int  main()
{
	shared_ptr<ListNode> node1(new ListNode)
	shared_ptr<ListNode> node2(new ListNode)
	node1 ->next_ = node2;
	node2 ->prev_ = node1;
return 0;
}
//注意 ;node1 想要释放,就需要node2不使用node1

;
Node2 want to release, you need to node1 not in use,
thus forming a circular reference,

Resulting in a reference count has been in node1 2;
node2 has a reference count of 2;

Solution, we will type pointer within the node instead weak_ptr;

Note weak_ptr is a special auxiliary shard_ptr; it does not increase the reference count:

struct ListNode
{
//weak_ptr  不会增加引用计数,专门辅助shared_ptr
weak_ptr<ListNode> prev_;//智能指针
weak_ptr<ListNode> next_;//智能指针
}

//即 一个ListNode 具有两个智能指针,
int  main()
{
	shared_ptr<ListNode> node1(new ListNode)
	shared_ptr<ListNode> node2(new ListNode)
	node1 ->next_ = node2;
	node2 ->prev_ = node1;
return 0;
}

C ++ cast:

1 Why C ++ has its own cast
c poor visibility in the type conversion is not easy to quickly locate the error position, c ++ type conversion for visibility, c ++ increased four casts.

Static_cast. 1
static_cast static type conversion (not available for polymorphism, etc.), and the type of conversion obtained have contact.

2 provides reinterpret_cast reinterpretation low-level bit pattern operand
reinterpret_cast for cast between different types.
3 const_cast for modifying const type variable.

Of dynamic_cast. 4
. 1 of dynamic_cast containing only the same class virtual function to
perform a pre-check 2 dynamic_cast will be successful, the conversion is performed, not, returns 0.

explicit: to prevent the implicit type conversion constructor

	eg: Date a = 6;
	内部其实 :  Date tmp(6);
						Date a(tmp) ;

Finally: We should try to avoid using C ++ casts, casts, will automatically suspend or shut down normal type-checking compiler does not issue a warning in place mandatory error

Published 90 original articles · won praise 13 · views 10000 +

Guess you like

Origin blog.csdn.net/weixin_44030580/article/details/104542270
Recommended