非线程安全的共享指针简单实现
#include <iostream>
using namespace std;
template<class T>
class MySharedPtr {
private:
int* count;
T* ptr;
public:
MySharedPtr(T* p = nullptr);//构造函数
MySharedPtr(const MySharedPtr<T>& other);//拷贝构造函数
MySharedPtr<T> &operator=(T* p);//赋值运算符
MySharedPtr<T> &operator=(const MySharedPtr<T>& other);//赋值运算符
T* operator->();//解引用所存储的指针
T& operator*();//解引用所存储的指针
int getReferance() {
return *count;
}
~MySharedPtr();
};
template<class T>
MySharedPtr<T>::MySharedPtr(T* p) {
cout << "constructor\n";
count = new int(1);
ptr = p;
}
template<class T>
MySharedPtr<T>::MySharedPtr(const MySharedPtr<T>& other) {
cout << "copy constructor\n";
if(this != &other) {
(*other.count)++;
count = other.count;
ptr = other.ptr;
}
}
template<class T>
MySharedPtr<T> &MySharedPtr<T>::operator=(T* p) {
cout << "operator=1\n";
if (ptr == p) {
return *this;
}
--*count;
if (*count == 0) {
delete count;
count = nullptr;
delete ptr;
ptr = nullptr;
}
count = new int(1);
ptr = p;
return *this;
}
template<class T>
MySharedPtr<T> &MySharedPtr<T>::operator=(const MySharedPtr<T>& other) {
cout << "operator=2\n";
if(this == &other) {
return *this;
}
--*count;
if (*count == 0) {
delete count;
count = nullptr;
delete ptr;
ptr = nullptr;
}
(*other.count)++;
ptr = other.ptr;
count = other.count;
return *this;
}
template<class T>
T* MySharedPtr<T>::operator->() {
cout << "operator ->\n";
return ptr;
}
template<class T>
T& MySharedPtr<T>::operator*() {
cout << "operator *\n";
return *ptr;
}
template<class T>
MySharedPtr<T>::~MySharedPtr() {
cout << "desconstructor ptr:" << ptr << " count:" << *count << "\n";
if (--*count == 0) {
delete count;
count = nullptr;
delete ptr;
ptr = nullptr;
}
}
class Test {
private:
public:
Test() {}
~Test() {}
void print() {
cout << "print\n";
}
};
int main() {
MySharedPtr<Test> ptr1(new Test());
cout << "ptr1 count:" << ptr1.getReferance() << "\n";
MySharedPtr<Test> ptr2 = ptr1;//拷贝构造函数
cout << "ptr1 count:" << ptr1.getReferance() << "\n";
MySharedPtr<Test> ptr3;
ptr3 = ptr2;
cout << "ptr1 count:" << ptr1.getReferance() << "\n";
MySharedPtr<Test> ptr4(new Test());
cout << "ptr4 count:" << ptr4.getReferance() << "\n";
MySharedPtr<Test> ptr5 = ptr1;
cout << "ptr1 count:" << ptr1.getReferance() << "\n";
MySharedPtr<Test> ptr6 = new Test();
cout << "ptr6 count:" << ptr6.getReferance() << "\n";
ptr5 = new Test();
cout << "ptr1 count:" << ptr1.getReferance() << "\n";
cout << "ptr5 count:" << ptr5.getReferance() << "\n";
ptr1->print();
(*ptr1).print();
}
线程安全实现源码
摘自MacOSX13.0.sdk
template <class _Tp>
inline _LIBCPP_INLINE_VISIBILITY _Tp
__libcpp_atomic_refcount_increment(_Tp& __t) _NOEXCEPT
{
#if defined(_LIBCPP_HAS_BUILTIN_ATOMIC_SUPPORT) && !defined(_LIBCPP_HAS_NO_THREADS)
return __atomic_add_fetch(&__t, 1, __ATOMIC_RELAXED);
#else
return __t += 1;
#endif
}
template <class _Tp>
inline _LIBCPP_INLINE_VISIBILITY _Tp
__libcpp_atomic_refcount_decrement(_Tp& __t) _NOEXCEPT
{
#if defined(_LIBCPP_HAS_BUILTIN_ATOMIC_SUPPORT) && !defined(_LIBCPP_HAS_NO_THREADS)
return __atomic_add_fetch(&__t, -1, __ATOMIC_ACQ_REL);
#else
return __t -= 1;
#endif
}
shared_ptr在引用计数器自增采用宽松操作:memory_order_relaxed
带标签 memory_order_relaxed 的原子操作无同步操作;它们不会在共时的内存访问间强加顺序。它们只保证原子性和修改顺序一致性。
1187





