現代 C++ 中,shared_ptr 屬非侵入式:控制區塊(引用計數、刪除器)與被管理物件分離,智慧指標內部持有兩個指標。侵入式則將引用計數直接置於被管理類別內部(通常透過繼承基類),智慧指標僅持有單一物件指標。


int(單執行緒、效能優先)。A = B 僅拷貝資料成員,保留 A 原有計數。// 原子計數類別(簡化版,實際需含記憶體屏障)
class Atomic {
volatile int _val;
public:
Atomic(int v = 0) : _val(v) {}
void inc_fast() { ++_val; }
bool dec_and_test() { return --_val == 0; }
int get() const { return _val; }
};
template<class T>
class HandleBaseT {
public:
typedef T atomic_type;
HandleBaseT& operator=(const HandleBaseT&) { return *this; } // 不拷貝計數
void incRef() { _atomic.inc_fast(); }
void decRef() {
if (_atomic.dec_and_test() && !_bNoDelete) {
_bNoDelete = true;
delete this;
}
}
int getRef() const { return _atomic.get(); }
void setNoDelete(bool b) { _bNoDelete = b; }
protected:
HandleBaseT() : _atomic(0), _bNoDelete(false) {}
HandleBaseT(const HandleBaseT&) : _atomic(0), _bNoDelete(false) {} // 計數歸零
virtual ~HandleBaseT() {}
atomic_type _atomic;
bool _bNoDelete;
};
// int 特化(非執行緒安全,效能較高)
template<> inline void HandleBaseT<int>::incRef() { ++_atomic; }
template<> inline void HandleBaseT<int>::decRef() {
if (--_atomic == 0 && !_bNoDelete) { _bNoDelete = true; delete this; }
}
template<> inline int HandleBaseT<int>::getRef() const { return _atomic; }
// 預設使用 Atomic
typedef HandleBaseT<Atomic> HandleBase;
struct Shared_PtrNull_Exception : public exception {
Shared_PtrNull_Exception(const string& msg) : exception(msg.c_str()) {}
};
template<typename T>
class Shared_Ptr {
public:
typedef T element_type;
// 由原生指標建構
Shared_Ptr(T* p = 0) : _ptr(p) { if (_ptr) _ptr->incRef(); }
// 由其他型別 Shared_Ptr 建構(支援多型轉換)
template<typename Y>
Shared_Ptr(const Shared_Ptr<Y>& r) : _ptr(r._ptr) { if (_ptr) _ptr->incRef(); }
// 拷貝建構
Shared_Ptr(const Shared_Ptr& r) : _ptr(r._ptr) { if (_ptr) _ptr->incRef(); }
~Shared_Ptr() { if (_ptr) _ptr->decRef(); }
// 指派:原生指標
Shared_Ptr& operator=(T* p) {
if (_ptr != p) {
if (p) p->incRef();
T* old = _ptr; _ptr = p;
if (old) old->decRef();
}
return *this;
}
// 指派:其他型別 Shared_Ptr
template<typename Y>
Shared_Ptr& operator=(const Shared_Ptr<Y>& r) {
if (_ptr != r._ptr) {
if (r._ptr) r._ptr->incRef();
T* old = _ptr; _ptr = r._ptr;
if (old) old->decRef();
}
return *this;
}
// 指派:同型別 Shared_Ptr
Shared_Ptr& operator=(const Shared_Ptr& r) {
if (_ptr != r._ptr) {
if (r._ptr) r._ptr->incRef();
T* old = _ptr; _ptr = r._ptr;
if (old) old->decRef();
}
return *this;
}
// 動態轉型輔助
template<class Y> static Shared_Ptr dynamicCast(const Shared_Ptr<Y>& r) {
return Shared_Ptr(dynamic_cast<T*>(r._ptr));
}
template<class Y> static Shared_Ptr dynamicCast(Y* p) {
return Shared_Ptr(dynamic_cast<T*>(p));
}
T* get() const { return _ptr; }
T* operator->() const { if (!_ptr) throw Shared_PtrNull_Exception("null handle"); return _ptr; }
T& operator*() const { if (!_ptr) throw Shared_PtrNull_Exception("null handle"); return *_ptr; }
operator bool() const { return _ptr != 0; }
void swap(Shared_Ptr& other) { std::swap(_ptr, other._ptr); }
protected:
void throwNullHandleException() const { throw Shared_PtrNull_Exception("shared_ptr null handle error"); }
public:
T* _ptr;
};
// 比較運算子(支援置於 map 等容器)
template<typename T, typename U>
inline bool operator==(const Shared_Ptr<T>& lhs, const Shared_Ptr<U>& rhs) {
T* l = lhs.get(); U* r = rhs.get();
return (l && r) ? *l == *r : (!l && !r);
}
template<typename T, typename U>
inline bool operator!=(const Shared_Ptr<T>& lhs, const Shared_Ptr<U>& rhs) {
T* l = lhs.get(); U* r = rhs.get();
return (l && r) ? *l != *r : (l || r);
}
template<typename T, typename U>
inline bool operator<(const Shared_Ptr<T>& lhs, const Shared_Ptr<U>& rhs) {
T* l = lhs.get(); U* r = rhs.get();
return (l && r) ? *l < *r : (!l && r);
}
class Test : public HandleBase {
// 業務邏輯...
};
int main() {
Shared_Ptr<Test> myTest = new Test(); // 自動管理引用計數
myTest->doSomething();
return 0;
}
此實作展示侵入式智慧指標的核心機制:基類封裝計數、智慧指標僅持有單一指標、支援多型轉換、執行緒安全(預設)。實際專案中可根據需求擴展自訂刪除器、弱引用等功能。