智能指針代碼:
// 引用計數器類 用於存儲指向同一對象的指針數
template<typename T>
class Counter
{
private:
// 數據成員
T* ptr; // 對象指針
int cnt; // 引用計數器
// 友元類聲明
template<typename T>
friend class SmartPtr;
// 成員函數
// 構造函數
Counter(T* p) // p爲指向動態分配對象的指針
{
ptr = p;
cnt = 1;
}
// 析構函數
~Counter()
{
delete ptr;
}
};
// 智能指針類
template<typename T>
class SmartPtr
{
private:
// 數據成員
T* ptr;
Counter<T>* ptr_cnt;
public:
// 普通構造函數 初始化計數類
SmartPtr(T* p) : ptr(p), ptr_cnt(new Counter<T>(p))
{
}
// 拷貝構造函數
SmartPtr(const SmartPtr& other) : ptr(other.ptr), ptr_cnt(other.ptr_cnt)
{
ptr_cnt->cnt++;
}
// 移動構造函數
SmartPtr(SmartPtr&& other) : ptr(std::move(other.ptr)), ptr_cnt(std::move(other.ptr_cnt))
{
other.ptr_cnt = nullptr;
}
// 賦值重載
SmartPtr& operator=(const SmartPtr& rhs)
{
if (ptr_cnt != rhs.ptr_cnt)
{
if (ptr_cnt != nullptr)
{
ptr_cnt->cnt--;
if (ptr_cnt->cnt == 0)
delete ptr_cnt;
}
ptr = rhs.ptr;
ptr_cnt = rhs.ptr_cnt;
rhs.ptr_cnt->cnt++;
}
return *this;
}
// 移動賦值重載
SmartPtr& operator=(SmartPtr && rhs)
{
if (ptr_cnt != rhs.ptr_cnt)
{
std::swap(this, rhs);
}
return *this;
}
// 析構函數
~SmartPtr()
{
if (ptr_cnt != nullptr)
{
ptr_cnt->cnt--;
if (ptr_cnt->cnt == 0)
delete ptr_cnt;
}
}
T& operator*() const { return *(ptr); }
T* operator&() const { return ptr; }
size_t use_count() const { return ptr_cnt->cnt; }
bool unique() const { return (ptr_cnt->cnt == 1); }
T* get() const { return ptr; }
};
測試代碼:
class test
{
public:
int n;
test(int i) :n(i)
{
std::cout << "c " << n << std::endl;
}
~test()
{
std::cout << "d " << n << std::endl;
}
};
int main(int argc, char** argv) {
SmartPtr<test> p1 = new test(1);//構造
std::cout << p1.use_count() << std::endl; //1?
SmartPtr<test> p2 = p1;//複製構造
std::cout << p1.use_count() << std::endl;//2?
std::cout << p1.get()->n << p2.get()->n << std::endl;//11?
SmartPtr<test> p3(std::move(p2));//移動構造
std::cout << p1.use_count() << std::endl;//2?
SmartPtr<test> p4 = new test(2);
p3 = p4;//賦值
std::cout << p4.use_count() << p1.use_count() << std::endl;//21?
return 0;
}
測試結果: