[크롬 소스 읽기] 크롬을 이해하는 스마트 포인트.

5191 단어
크롬 코드에는 스마트 포인터를 많이 활용해 대상의 포인터를 관리해 대상의 생명기 문제를 해결한다.이 글은 크롬에 정의된 몇 개의 스마트 포인터 종류를 이해하려고 시도하고 있다.
1. scoped_ptr/scoped_array/scopred_array_malloc
scopred로 시작하는 스마트 포인터 클래스는/src/base/scopedptr.h 파일에서그것들은 new/new[]/malloc에서 나온 대상 지침을 간단하게 포장하여 대상의 메모리 분배와 방출을 관리하는 명확한 디자인 목표를 가지고 있다.예를 들면 scopedptr류는 new/delete에 대해 간단한 포장을 하고 std::auto 와 유사하게 제공합니다ptr와 유사한 인터페이스, 그러나 std::auto 제거ptr 디자인에서 비난받는 복사 복사 시 관리되는 대상의 이동 문제간단하게 복사 및 복사 함수를 비활성화하면 이 효과를 얻을 수 있습니다.그래서 사용 장소가 매우 명확하고 간단하며 제한적이다.
[cpp]  view plain copy print ?
//   {  
//     scoped_ptr foo;          // No pointer managed.  
//     foo.reset(new Foo("wee"));    // Now a pointer is managed.  
//     foo.reset(new Foo("wee2"));   // Foo("wee") was destroyed.  
//     foo.reset(new Foo("wee3"));   // Foo("wee2") was destroyed.  
//     foo->Method();                // Foo::Method() called.  
//     foo.get()->Method();          // Foo::Method() called.  
//     SomeFunc(foo.Release());      // SomeFunc takes owernship, foo no longer  
//                                   // manages a pointer.  
//     foo.reset(new Foo("wee4"));   // foo manages a pointer again.  
//     foo.reset();                  // Foo("wee4") destroyed, foo no longer  
//                                   // manages a pointer.  
//   }  // foo wasn't managing a pointer, so nothing was destroyed.  
또한 두 개의 스마트 포인터 간의 비교도 금지한다. 왜냐하면 한 대상이 두 개의 스마트 포인터에 의해 동시에 관리되는 것을 허용하지 않기 때문이다.
[cpp]  view plain copy print ?
private:  
  // Forbid comparison of scoped_ptr types.  If C2 != C, it totally doesn't  
  // make sense, and if C2 == C, it still doesn't make sense because you should  
  // never have the same object owned by two different scoped_ptrs.  
  template  bool operator==(scoped_ptr const& p2) const;  
  template  bool operator!=(scoped_ptr const& p2) const;  
주의해야 할 점은 클래스의 많은 함수는 컴파일러의 검사 메커니즘을 사용합니다.
[cpp]  view plain copy print ?
~scoped_ptr() {  
  enum { type_must_be_complete = sizeof(C) };  
  delete ptr_;  
}  
따라서 이러한 템플릿 클래스를 컴파일할 때 관리 대상의 정의를 알아야 한다.즉 관리된 대상의 정의는 이러한 템플릿 클래스의 정의 전에 제시해야 한다.
2. scoped_refptr/RefCounted/RefCountedThreadSafe
위에서 소개한 간단한 스마트 포인터를 제외하고 또 하나의 광범위하게 사용되는 스마트 포인터는 스마트 포인터를 대상으로 하는 것이다. 예를 들어boost::sharedptr류, 그것이 바로 scopedrefptr.그것이 관리하는 대상은 템플릿 클래스인 RefCounted에 계승되어야 하며 T는 그 자체이다.RefCounted 템플릿은 AddRef와 Release 함수를 제공합니다. (yy, 왜 IncRef와 DecRef라고 부르지 않는지 의미가 명확하지 않습니까?)또한 INT 유형의 참조 개수도 유지됩니다.RefCountedThreadSafe는 라인이 안전한 RefCounted 버전입니다. 인용 계수는 INT 형식이 아니라 AtomicRefCount 형식(원자의)이기 때문입니다.
저희가 포인트를 두고 scopedrefptr 템플릿 클래스:
[cpp]  view plain copy print ?
template   
class scoped_refptr {  
 public:  
  scoped_refptr() : ptr_(NULL) {  
  }  
  
  scoped_refptr(T* p) : ptr_(p) {  
    if (ptr_)  
      ptr_->AddRef();  
  }  
  
  scoped_refptr(const scoped_refptr& r) : ptr_(r.ptr_) {  
    if (ptr_)  
      ptr_->AddRef();  
  }  
  
  ~scoped_refptr() {  
    if (ptr_)  
      ptr_->Release();  
  }  
  
  T* get() const { return ptr_; }  
  operator T*() const { return ptr_; }  
  T* operator->() const { return ptr_; }  
  
  scoped_refptr& operator=(T* p) {  
    // AddRef first so that self assignment should work  
    if (p)  
      p->AddRef();  
    if (ptr_ )  
      ptr_ ->Release();  
    ptr_ = p;  
    return *this;  
  }  
  
  scoped_refptr& operator=(const scoped_refptr& r) {  
    return *this = r.ptr_;  
  }  
  
  void swap(T** pp) {  
    T* p = ptr_;  
    ptr_ = *pp;  
    *pp = p;  
  }  
  
  void swap(scoped_refptr& r) {  
    swap(&r.ptr_);  
  }  
  
 protected:  
  T* ptr_;  
};  
scoped_refptr 및 boost::sharedptr의 차이점:
boost::shared_ptr는 복사 구조와 부수 연산자가 호출될 때마다 인용 계수를 관리합니다.반면scopedrefptr는 인용 계수를 관리하지 않고 대상이 스스로 관리합니다.이렇게 하면 다음과 같은 다른 용법을 가져올 수 있다.
boost::shared_ptr의 용례(올바르지 않음):
[cpp]  view plain copy print ?
int* pa = new int(3);  
{  
    boost::shared_ptr psa(pa);  
    ...  
    boost::shared_ptr psb(pa);  
}  
psa/psb가 소각되었을 때pa를 삭제하려고 시도한 결과 더블-delete 문제가 발생했습니다.
하면, 만약, 만약...ptr, 그러면 상술한 문제가 발생하지 않을 것입니다.
스마트 포인터의 소유권 정책 기술에는 deep copy,reference counting,reference linking,destructive copy가 있습니다. 서적 7장 5절에서 이 몇 가지 기술의 장단점을 상세하게 설명했고 Loki 라이브러리도 이 몇 가지 전략 기술의 실제 버전을 제공했다.Chrome의 스마트 포인터와 boost::sharedptr는 모두 Reference counting 기술을 채택한다.

좋은 웹페이지 즐겨찾기