我正在阅读 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 . . .
*/
答案 0 :(得分:3)
问题在于:
refThirdPointer = pFirstInt;
从已经由另一个智能指针管理的原始指针进行分配。
因此,您最终会有两个不相关的智能指针试图管理pFirstInt
。它们是无关的,因为它们有各自的参考计数,并且幸福地没有意识到彼此的存在。这导致您正在观察的双重删除。