c++中的智能指针引用计数

Smart pointer reference counting in C++

本文关键字:引用 指针 智能 c++      更新时间:2023-10-16

我正在阅读Safe c++ ,我对引用计数有疑问。问题在下面的代码注释部分提供?

#include <iostream>
using namespace std;
template <typename T>class RefCountPtr {
public: 
    explicit RefCountPtr(T* p = NULL) {
            Create(p);      
    }
    RefCountPtr(const RefCountPtr<T>& rhs) {
        Copy(rhs);      
    }
    RefCountPtr<T>& operator=(const RefCountPtr<T>& rhs) {  
        if(ptr_ != rhs.ptr_) {
            Kill();         
            Copy(rhs);  
        }
        return *this;   
    }
    RefCountPtr<T>& operator=(T* p) {
        if(ptr_ != p) { 
            Kill();     
            Create(p);  
        }   
        return *this;
    }   
    ~RefCountPtr() {
        Kill();
    }
    T* Get() const {
        return ptr_; 
    }
    T* operator->() const { 
        // SCPP_TEST_ASSERT(ptr_ != NULL, "Attempt to use operator -> on NULL pointer.");   
        return ptr_;    
    }   
    T& operator* () const { 
        // SCPP_TEST_ASSERT(ptr_ != NULL, "Attempt to use operator * on NULL pointer.");
        return *ptr_;   
    }
    int GetCount() { return *count_; }
private:    
    T*  ptr_;
    int*    count_;
    void Create(T* p) { 
        ptr_ = p;   
        if(ptr_ != NULL) {
            count_ = new int;
            *count_ = 1;    
        } else {
            count_ = NULL;  
        }   
    }   
    void Copy(const RefCountPtr<T>& rhs) {  
        ptr_ = rhs.ptr_;
        count_ = rhs.count_;
        if(count_ != NULL)  
            ++(*count_);
    }   
    void Kill() {   
        if(count_ != NULL) {
            if(--(*count_) == 0) {  
                delete ptr_;    
                delete count_;  
            }   
        }   
    }
};
void main()
{
    int* pFirstInt = new int;
    RefCountPtr<int> refPointer(pFirstInt);
    cout << "count: " << refPointer.GetCount() << std::endl;
    RefCountPtr<int> refSecondPointer = refPointer; // this calls copy constructor.
    cout << "second count: " << refSecondPointer.GetCount() << std::endl;
    RefCountPtr<int> refThirdPointer;
    refThirdPointer = pFirstInt; **// Question why are we not incrementing same int pointer? How can we correct this?
                                 // If we are not incrementing same pointer why author has provided 
                                 // operator = for data type T? 
                                 // Note: As expected program is crashing while exiting as we are deleting int pointer twice.**
    std::cout << "Third pointer: " << refThirdPointer.GetCount() << std::endl;
    RefCountPtr<int> refFourthPointer;
    refFourthPointer = refSecondPointer;
    cout << "Fourth count: " << refFourthPointer.GetCount() << std::endl;
    return;
}
/*
count: 1
second count: 2
Third pointer: 1
Fourth count: 3
Press any key to continue . . .
*/

问题是:

refThirdPointer = pFirstInt;

从一个已经被另一个智能指针管理的原始指针进行赋值。

因此,你最终有两个不相关的智能指针试图管理pFirstInt。它们是不相关的,因为它们有各自的引用计数,并且幸福地不知道彼此的存在。这会导致您正在观察的双重删除。