实现智能指针

xiaoxiao2021-02-28  45

AutoPtr

资源的转移不推荐使用。 旧库使用拥有者会导致野指针

实现代码

template <class T> class AutoPtr { public: AutoPtr(T* p = NULL) : _ptr(p) {} AutoPtr(AutoPtr<T>& ap) :_ptr(ap._ptr) { ap._ptr = NULL; } AutoPtr<T>& operator=(AutoPtr<T>& ap) { if (this != &ap) { delete _ptr; _ptr = ap._ptr; ap._ptr = NULL; } return *this; } ~AutoPtr() { if (_ptr) { delete _ptr; _ptr = NULL; } } T* GetPtr() { return _ptr; } const T* GetPtr()const { return _ptr; } T& operator*() { return *_ptr; } const T& operator*()const { return *_ptr; } T* operator->() { return _ptr; } const T* operator->()const { return _ptr; } private: T* _ptr; };

测试用例

void Test_AutoPtr() { /* * 测试构造函数拷贝拷贝构造 */ AutoPtr<int> ap1(new int(20)); std::cout << *ap1 << std::endl; AutoPtr<int> ap2(ap1); std::cout << *ap2 << std::endl; /* * 测试 operator = 和 -> * */ struct A { int a; int b; }; AutoPtr<A> ap3(new A); ap3->a = 2; ap3->b = 3; std::cout << (*ap3).a << std::endl; std::cout << (*ap3).b << std::endl; AutoPtr<A> ap4; ap4 = ap3; std::cout << (*ap4).a << std::endl; std::cout << (*ap4).b << std::endl; }

输出结果

20 20 2 3 2 3

ScopedPtr / Unique_ptr

unique_ptr 是 c++11 标识, ScopedPtr 是 boost库提供 还有ScopedAarray

实现代码

template <class T> class ScopedPtr { public: ScopedPtr(T* p = NULL) : _ptr(p) {} ~ScopedPtr() { if (_ptr) { delete _ptr; _ptr = NULL; } } T* operator->() { return _ptr; } const T* operator->()const { return _ptr; } T& operator*() { return *_ptr; } const T& operator*()const { return *_ptr; } T* GetPtr() { return _ptr; } const T* GetPtr()const { return _ptr; } private: ScopedPtr(const ScopedPtr<T>&); ScopedPtr<T>& operator=(const ScopedPtr<T>&); private: T* _ptr; };

测试用例

void Test_ScopedPtr() { ScopedPtr<int> sp1(new int(20)); std::cout << *sp1 << std::endl; //ScopedPtr<int> sp2(sp1); // error 拷贝构造函数为私有 ScopedPtr<int> sp3(new int(30)); //sp3 = sp1; // error 赋值运算符私有 方式拷贝 struct A { int a; int b; }; ScopedPtr<A> sp4(new A); sp4->a = 1; sp4->b = 2; std::cout << (*sp4).a << std::endl; std::cout << (*sp4).b<< std::endl; }

输出结果

20 1 2

ScopedArray

实现代码

template <class T> class ScopedArray { public: ScopedArray(T* p = NULL) : _ptr(p) {} ~ScopedArray() { if (_ptr) { delete[] _ptr; _ptr = NULL; } } T& operator[](size_t index) { return _ptr[index]; } const T& operator[](size_t index)const { return _ptr[index]; } private: ScopedArray(const ScopedArray<T>&); ScopedArray<T>& operator=(const ScopedArray<T>&); private: T* _ptr; };

测试用例

void Test_ScopedArray() { ScopedArray<int> spa1(new int[10]); spa1[0] = 20; std::cout << spa1[0] << std::endl; ScopedArray<int> spa2(new int[20]); // spa2 = spa1; // error ,operator = 为私有 // ScopedArray<int> spa3(spa1); // error 拷贝构造为私有 struct A { int a; int b; }; ScopedArray<A> spa4(new A[10]); spa4[0].a = 1; spa4[0].b = 2; std::cout << spa4[0].a << std::endl; std::cout << spa4[0].b << std::endl; }

输出结果

20 1 2

SharedPtr

存在的问题,循环引用,weak_ptr解决。他不会占用引用计数,必须用一个sharedptr来赋值。 shared 定制删除器。 C++11 提供了 shared_ptr。Boost提供了shared_ptr 和 sharedarray。

实现代码

template <class T> class SharedPtr { public: explicit SharedPtr(T* p = NULL) : _ptr(p) , _pcount(new unsigned int(1)) {} explicit SharedPtr(const SharedPtr<T>& sp) :_ptr(sp._ptr) , _pcount(sp._pcount) { ++(*_pcount); } SharedPtr<T>& operator=(const SharedPtr<T>& sp) { if (this != &sp) { if ((--(*_pcount)) == 0) { delete _pcount; delete _ptr; } _ptr = sp._ptr; _pcount = sp._pcount; ++(*_pcount); } return *this; } ~SharedPtr() { if ((--(*_pcount)) == 0) { delete _ptr; delete _pcount; } } unsigned int UseCount()const { return *_pcount; } T& operator*() { return *_ptr; } const T& operator*()const { return *_ptr; } T* operator->() { return _ptr; } const T* operator->()const { return _ptr; } T* GetPtr() { return _ptr; } const T* GetPtr()const { return _ptr; } private: T* _ptr; unsigned int* _pcount; };

测试用例

void Test_ShareddPtr() { SharedPtr<int> sp1(new int(2)); sp1 = sp1; std::cout << sp1.UseCount() << std::endl; std::cout << *sp1 << std::endl; SharedPtr<int> sp2(sp1); std::cout << sp1.UseCount() << std::endl; SharedPtr<int> sp3; sp3 = sp1; std::cout << sp1.UseCount() << std::endl; SharedPtr<int> sp4(new int(4)); std::cout << sp4.UseCount() << std::endl; sp4 = sp1; std::cout << sp4.UseCount() << std::endl; std::cout << sp1.UseCount() << std::endl; }

输出结果

1 2 2 3 1 4 4
转载请注明原文地址: https://www.6miu.com/read-59956.html

最新回复(0)