C++스마트 포인터 의 시 뮬 레이 션 구현 인 스 턴 스

8464 단어 지능.포인터
C++스마트 포인터 의 시 뮬 레이 션 구현 인 스 턴 스
1.도입

int main()
{
  int *p = new int;  //   
  delete p;
  return 0;
}
위의 코드 에서 누 드 포인터 p 를 정 의 했 습 니 다.수 동 으로 풀 어야 합 니 다.만약 우리 가 조심 하지 않 아 이 지침 을 놓 는 것 을 잊 거나 이 지침 을 놓 기 전에 약간의 이상 이 발생 하면 심각 한 결 과 를 초래 할 수 있다(메모리 유출).스마트 포인터 도 이런 문 제 를 해결 하고 프로그래머 들 이 포인터 사용 에 전념 하여 메모리 관 리 를 스마트 포인터 에 게 맡 기 는 데 주력 하고 있다.
보통 지침 에 도 지침 이 걸 리 기 쉬 워 요.여러 개의 지침 이 같은 대상 을 가리 킬 때 어떤 지침 이 이 대상 을 delete 했 기 때문에 이 지침 은 이 대상 을 조작 하지 않 습 니 다.그러면 다른 대상 을 가리 키 는 지침 은 요?삭 제 된 기본 대상 을 기다 리 고 있 으 며 언제든지 조작 할 준비 가 되 어 있 습 니 다.그래서 현수 포인터 가 형성 되 었 고 프로그램 이 무 너 질 날 도 멀 지 않 았 다.

int main()
{
  int *p1 = new int(2);
  int *p2 = p1;
  int *p3 = p2;
  cout<<*p1<<endl;
  cout<<*p2<<endl;
  cout<<*p3<<endl;
  delete p1;
  cout<<*p2<<endl;
  return 0;
}
출력 결과

2
2
2
-572662307
출력 결과*p2 의 결 과 는 기대 중 2 가 아 닙 니 다.2 가 이미 삭제 되 었 기 때 문 입 니 다.


지능 포인터
지능 지침 은 일반 지침 을 봉 하여 일반 지침 과 같은 기능 을 실현 할 수 있 는 유형 이다.다른 것 은 스마트 포인터 가 메모 리 를 자동 으로 관리 할 수 있 고 클래스 대상 을 이용 하여 역할 도 메 인 을 호출 하여 포인터 에 대한 방출 을 분석 함수 에 적어 서 포인터 가 걸 리 는 상황 이 발생 하지 않도록 하 는 것 이다.
스마트 포인터(smart pointer)는 동적 분배(더미)대상 을 가리 키 는 지침 을 저장 하 는 클래스 로 생존 기 제어 에 사용 되 며 동적 분배 대상 을 자동 으로 정확하게 소각 하여 메모리 유출 을 방지 할 수 있다.그것 의 일반적인 실현 기술 은 인용 계수(reference count)를 사용 하 는 것 이다.스마트 포인터 류 는 하나의 계수 기 를 클래스 가 가리 키 는 대상 과 연결 시 키 고 이 클래스 가 몇 개의 대상 이 같은 지침 을 공유 하 는 지 를 참조 하여 추적 합 니 다.클래스 의 새 대상 을 만 들 때마다 포인터 를 초기 화하 고 인용 수 를 1 로 설정 합 니 다.대상 이 다른 대상 의 복사 본 으로 만 들 때 구조 함수 복사 지침 을 복사 하고 이에 상응하는 인용 수 를 증가 합 니 다.한 대상 에 게 할당 을 할 때 할당 연산 자 는 왼쪽 연산 자가 가리 키 는 대상 의 인용 수 를 줄 이 고(인용 계수 가 0 으로 줄 어 들 면 대상 을 삭제 합 니 다)오른쪽 연산 자가 가리 키 는 대상 의 인용 수 를 증가 합 니 다.석조 함 수 를 호출 할 때 구조 함 수 는 인용 계 수 를 줄 입 니 다(인용 계수 가 0 으로 줄 어 들 면 기본 대상 을 삭제 합 니 다).
지능 지침 은 지침 동작 을 모 의 하 는 유형 이다.모든 스마트 포인터 가 다시 불 러 옵 니 다.->와*연산 자 입 니 다.지능 지침 에는 또 많은 다른 기능 이 있 는데,비교적 유용 한 것 은 자동 소각 이다.이것 은 주로 창고 대상 의 유한 작용 역 과 임시 대상(유한 작용 역 실현)분석 함 수 를 이용 하여 메모 리 를 방출 한다.물론 스마트 포인 터 는 이 뿐만 이 아니 라 복사 시 원본 대상 을 수정 할 수 있 는 등 도 포함 된다.스마트 포인터 가 수요 에 따라 디자인 도 다르다.auto_ptr 는 흔히 볼 수 있 는 스마트 지침 이다.
지능 포인터 의 실현(클래스 템 플 릿 으로 구현)

class Test
{
public:
  Test()
  {
    cout<<"Test()"<<endl;
  }
  ~Test()
  {
    cout<<"~Test()"<<endl;
  }
  void func()
  {
    cout<<"call Test::func()"<<endl;
  }
};
template<typename T>
class CSmartptr
{
public:
  CSmartptr(T *ptr):_ptr(ptr)
  {cout<<"CSmartptr()"<<endl;}
  CSmartptr(const CSmartptr<T> &other)
  {
    _ptr = new T;
    *ptr = *other._ptr;
  }
  ~CSmartptr()
  {
    cout<<"~CSmartptr()"<<endl;
    delete _ptr;
  }
  void relase() const
  {
    ((CSmartptr<T> *)this)->owns = false;
  }
  T& operator*()
  {
    return *_ptr;
  }
  const T& operator*()const {return *_ptr;}
  T *operator->()
  {
    return _ptr;
  }
  const T *operator->()const {return _ptr;}
private:
  T *_ptr;
};
int main()
{
  CSmartptr<int> p1(new int);
  *p1 = 200;
  CSmartptr<Test> p2(new Test);
  p2->func();
  return 0;
}
아 날로 그 실현 autoptr

template<typename T>
class CSmartptr
{
public:
  CSmartptr(T *ptr):_ptr(ptr),owns(true){cout<<"CSmartptr()"<<endl;}
  CSmartptr(const CSmartptr<T> &other)
  {
    other.relase();
    _ptr = other._ptr;
  }
  ~CSmartptr()
  {
    cout<<"~CSmartptr()"<<endl;
    if( owns == true)
    {
      cout<<"~CSmartptr()"<<endl;
      delete _ptr;
    }

  }
  void relase() const
  {
    ((CSmartptr<T> *)this)->owns = false;
  }
  T& operator*()
  {
    return *_ptr;
  }
  const T& operator*()const {return *_ptr;}
  T *operator->()
  {
    return _ptr;
  }
  const T *operator->()const {return _ptr;}
private:
  T *_ptr;
  bool owns; //    ,           
};
int main()
{
  CSmartptr<int> p1(new int);
  *p1 = 200;
  CSmartptr<Test> p2(new Test);
  p2->func();
  return 0;
}

인용 계수 가 있 는 스마트 포인터(자원 관리 와 방출 에 편리 함)

class CHeapTable
{
public:
  static CHeapTable& getInstance()
  {
    return mHeapTable;
  }
  //      
  void addRef(void *ptr)
  {
    pthread_mutex_lock(mutex);
    list<Node>::iterator it = find(mList.begin(),
      mList.end(), ptr); // Node == Node it->mpaddr
    if(it == mList.end())
    {
      mList.push_front(ptr);
      cout<<"new addr:"<<ptr<<" ref:"<<1<<endl;
    }
    else
    {
      it->mcount++;
      cout<<"add addr:"<<ptr<<" ref:"<<it->mcount<<endl;
    }
    pthread_mutex_unlock(mutex);
  }
  //       
  void delRef(void *ptr)
  {
    list<Node>::iterator it = find(mList.begin(),
      mList.end(), ptr);
    if(it != mList.end())
    {
      it->mcount--;
      cout<<"del addr:"<<ptr<<" ref:"<<it->mcount<<endl;
      if(it->mcount == 0)
      {
        mList.erase(it);
      }
    }
  }
  //       
  int getRef(void *ptr)
  {
    list<Node>::iterator it = find(mList.begin(),
      mList.end(), ptr);
    if(it != mList.end())
    {
      return it->mcount;
    }
    return 0;
  }
private:
  CHeapTable(){}
  static CHeapTable mHeapTable;

  struct Node
  {
    Node(void *ptr=NULL):mpaddr(ptr),mcount(1){}
    bool operator==(const Node &src)
    {
      return mpaddr == src.mpaddr;
    }
    void *mpaddr; //       
    int mcount; //         
  };

  list<Node> mList;
};
CHeapTable CHeapTable::mHeapTable;
template<typename T>
class CSmartPtr
{
public:
  CSmartPtr(T *ptr = NULL)
    :mptr(ptr)
  {
    if(mptr != NULL)
    {
      addRef();
    }
  }
  ~CSmartPtr()
  {
    delRef();
    if(0 == getRef())
    {
      delete mptr; 
      mptr = NULL;
    }
  }

  CSmartPtr(const CSmartPtr<T> &src)
    :mptr(src.mptr)
  {
    if(mptr != NULL)
    {
      addRef();
    }
  }

  CSmartPtr<T>& operator=(const CSmartPtr<T> &src)
  {
    if(this == &src)
      return *this;

    delRef();
    if(0 == getRef())
    {
      delete mptr;
      mptr = NULL;
    }

    mptr = src.mptr;
    if(mptr != NULL)
    {
      addRef();
    }
  }
  T& operator*(){return *mptr;}
  const T& operator*()const{return *mptr;}
  T* operator->(){return mptr;}
  const T* operator->()const{return mptr;}

  void addRef(){mHeapTable.addRef(mptr);}
  void delRef(){mHeapTable.delRef(mptr);}
  int getRef(){return mHeapTable.getRef(mptr);}
private:
  T *mptr;
   static CHeapTable &mHeapTable;
};
template<typename T>
CHeapTable& CSmartPtr<T>::mHeapTable = CHeapTable::getInstance();

이상 은 바로 스마트 포인터 의 사례 상세 한 설명 입 니 다.궁금 한 점 이 있 으 시 면 메 시 지 를 남기 거나 본 사이트 지역사회 에 가서 토론 을 하 십시오.읽 어 주 셔 서 감사합니다. 도움 이 되 셨 으 면 좋 겠 습 니 다.본 사이트 에 대한 지지 에 감 사 드 립 니 다.

좋은 웹페이지 즐겨찾기