关于智能指针

实现自己的智能指针

//智能指针 保证能做到资源的自动释放
//利用栈上的对象出作用域自动析构的特征,来做到资源的自动释放的
template<typename T>
class CSmartPtr
{
public:
	CSmartPtr(T *ptr = nullptr)
		:mptr(ptr) {}
	~CSmartPtr() { delete mptr; }
private:
	T *mptr;
};

int main()
{
	CSmartPtr<int> ptr1(new int);
	return 0;
}

不能把智能指针new在堆上

CSmartPtr *p = new CSmartPtr(new int); //p还是裸指针

重载*->

//智能指针 保证能做到资源的自动释放
//利用栈上的对象出作用域自动析构的特征,来做到资源的自动释放的
template<typename T>
class CSmartPtr
{
public:
	CSmartPtr(T *ptr = nullptr)
		:mptr(ptr) {}
	~CSmartPtr() { delete mptr; }

	T& operator*() { return *mptr; }
	T* operator->() { return mptr; }
private:
	T *mptr;
};

int main()
{
	CSmartPtr<int> ptr1(new int);
	class Test
	{
	public:
		void test() { cout << "Test::test()" << endl; }
	};

	CSmartPtr<Test> test(new Test());
	test->test();

	return 0;
}
	/*
	不带引用计数的智能指针
	auto_ptr:C++库里面
	C++11新标准:
	scoped_ptr
	unique_ptr
	*/

	auto_ptr<int> ptr1(new int);
	auto_ptr<int> ptr2(ptr1);

	*ptr2 = 20;
	cout << *ptr1 << endl; //ptr1现在为空

	//不推荐使用auto_ptr


//scoped_ptr
//scoped_ptr(const scoped_ptr&) = delete;
//scoped_ptr& operator=(const scoped_ptr&) = delete;

	unique_ptr
	unique_ptr(const unique_ptr<T>&) = delete;
	unique_ptr<T>& operator=(const unique_ptr<T>&) = delete;
	//实现了右值引用的拷贝
	unique_ptr(unique_ptr<T> &&src)
	unique_ptr<T>& operator=(unique_ptr<T> &&src)

	template<typename T>
	unique_ptr<T> getSmartPtr()
	{
		unique_ptr<T> ptr(new T());
		return ptr;
	}

	unique_ptr<int> ptr1 = getSmartPtr<int>();
	
	unique_ptr<int> p1(new int);
	unique_ptr<int> p2(std::move(p1));

引用计数

//对资源进行引用计数的类
template<typename T>
class RefCnt
{
public:
	RefCnt(T *ptr = nullptr)
		:mptr(ptr)
	{
		if (mptr != nullptr)
			mcount = 1;
	}
	//增加资源的引用计数
	void addRef()
	{
		mcount++;
	}
	int delRef() { return --mcount; }
private:
	T *mptr;
	int mcount;
};

//智能指针 保证能做到资源的自动释放
//利用栈上的对象出作用域自动析构的特征,来做到资源的自动释放的
template<typename T>
class CSmartPtr
{
public:
	CSmartPtr(T *ptr = nullptr)
		:mptr(ptr) 
	{
		mpRefCnt = new RefCnt<T>(mptr);
	}
	~CSmartPtr() 
	{ 
		if (0 == mpRefCnt->delRef())
		{
			delete mptr; 
			mptr = nullptr;
		}
	}

	T& operator*() { return *mptr; }
	T* operator->() { return mptr; }

	CSmartPtr(const CSmartPtr<T> &src)
		:mptr(src.mptr), mpRefCnt(src.mpRefCnt)
	{
		if (mptr != nullptr)
			mpRefCnt->addRef();
	}

	CSmartPtr<T>& operator=(const CSmartPtr<T> &src)
	{
		if (this == &src)
			return *this;

		if (0 == mpRefCnt->delRef())
		{
			delete mptr;
		}
		mptr = src.mptr;
		mpRefCnt = src.mpRefCnt;
		mpRefCnt->addRef();
		return *this;
	}
private:
	T *mptr; //指向资源的指针
	RefCnt<T> *mpRefCnt; //指向该资源引用计数对象的指针
};
int main()
{
	CSmartPtr<int> ptr1(new int);
	CSmartPtr<int> ptr2(ptr1);
	CSmartPtr<int> ptr3;
	ptr3 = ptr2;

	*ptr1 = 20;

	cout << *ptr2 << " " << *ptr3 << endl;
	return 0;
}

循环引用

class B;
class A
{
public:
	A() { cout << "A()" << endl; }
	~A() { cout << "~A()" << endl; }
	shared_ptr<B> _ptrb;
};

class B
{
public:
	B() { cout << "B()" << endl; }
	~B() { cout << "~B()" << endl; }
	shared_ptr<A> _ptra;
};


int main()
{
	shared_ptr<A> pa(new A());
	shared_ptr<B> pb(new B());

	pa->_ptrb = pb;
	pb->_ptra = pa;

	cout << pa.use_count() << endl;
	cout << pb.use_count() << endl;
	return 0;
}

定义对象的时候,用强智能指针;引用对象的地方,使用弱智能指针

class B;
class A
{
public:
	A() { cout << "A()" << endl; }
	~A() { cout << "~A()" << endl; }
	weak_ptr<B> _ptrb;
};

class B
{
public:
	B() { cout << "B()" << endl; }
	~B() { cout << "~B()" << endl; }
	weak_ptr<A> _ptra;
};


int main()
{
	shared_ptr<A> pa(new A());
	shared_ptr<B> pb(new B());

	pa->_ptrb = pb;
	pb->_ptra = pa;

	cout << pa.use_count() << endl;
	cout << pb.use_count() << endl;
	return 0;
}

weak_ptr只是观察作用,观察资源还可不可用,但是却不能用

class B;
class A
{
public:
	A() { cout << "A()" << endl; }
	~A() { cout << "~A()" << endl; }
	void testA() { cout << "非常好用的方法" << endl; }
	weak_ptr<B> _ptrb;
};

class B
{
public:
	B() { cout << "B()" << endl; }
	~B() { cout << "~B()" << endl; }
	void func()
	{
		_ptra->testA();//使用不了
	}
	weak_ptr<A> _ptra;
};

在使用时必须进行提升

class B
{
public:
	B() { cout << "B()" << endl; }
	~B() { cout << "~B()" << endl; }
	void func()
	{
		//_ptra->testA();//使用不了
		shared_ptr<A> ps = _ptra.lock(); //提升方法
		if (ps != nullptr)
		{
			ps->testA();
		}
	}
	weak_ptr<A> _ptra;
};
//多线程访问共享对象的线程安全问题
class A
{
public:
	A() { cout << "A()" << endl; }
	~A() { cout << "~A()" << endl; }
	void testA() { cout << "非常好用的方法!" << endl; }
};

void handler01(A *q)
{
	std::this_thread::sleep_for(std::chrono::seconds(2));
	//q访问A对象的时候,需要侦测一下A对象是否存活
	q->testA();
}

int main()
{
	A *p = new A();
	thread t1(handler01, p);

	delete p;

	t1.join();

	return 0;
}
class A
{
public:
	A() { cout << "A()" << endl; }
	~A() { cout << "~A()" << endl; }
	void testA() { cout << "非常好用的方法!" << endl; }
};

void handler01(weak_ptr<A> pw)
{
	std::this_thread::sleep_for(std::chrono::seconds(2));
	shared_ptr<A> sp = pw.lock();
	if (sp != nullptr)
	{
		sp->testA();
	}
	else
	{
		cout << "A对象已经析构,不能访问" << endl;
	}
}

int main()
{
	{
		shared_ptr<A> p(new A());
		thread t1(handler01, weak_ptr<A>(p));
		t1.detach();
	}

	std::this_thread::sleep_for(std::chrono::seconds(20));
	return 0;
}
/*
智能指针的删除器 deletor
智能指针:能够保证资源绝对的释放
*/
//unique_ptr shared_ptr
/*
~unique_ptr() {是一个函数对象的调用 deletor(ptr); }
template
class Deletor
{
public:
	void operator()(T *ptr)
	{
		delete ptr;
	}
};
*/

template<typename T>
class MyDeletor
{
public:
	void operator()(T *ptr) const
	{
		cout << "call MyDeletor.operator()" << endl;
		delete []ptr;
	}
};

int main()
{
	unique_ptr<int, MyDeletor<int>> ptr1(new int[100]);

	return 0;
}
template<typename T>
class MyFileDeletor
{
public:
	void operator()(T *ptr) const
	{
		cout << "call MyFileDeletor.operator()" << endl;
		fclose(ptr);
	}
};

int main()
{
	unique_ptr<FILE, MyFileDeletor<FILE>> ptr(fopen("data.txt", "w"));

	return 0;
}

使用lambda

	unique_ptr<int, function<void(int*)>> ptr1(new int[100],
		[](int *p)->void {
			cout << "call lambda release new int[100]" << endl;
			delete[]p;
		}
	);

	unique_ptr<FILE, function<void(FILE*)>> ptr2(fopen("data.txt", "w"),
		[](FILE *p)->void {
		cout << "call lambda release fopen" << endl;
		fclose(p);
	}
	);

你可能感兴趣的:(java,开发语言)