C++智能指针由来与实现思想以及实现一个简单的指针指针

智能指针的由来和基本思想

裸指针int *p = new int; ,其实就是C风格的指针。

裸指针的缺点:
1.必须手动释放资源,手动调用delete;
2.由于程序逻辑的错误return或者throw异常,导致释放资源的代码delete ptr没有被调用到;
3.程序运行过程中,发生异常,导致释放资源的代码没有被调用到。

智能指针 : 智能(不管程序运行发生什么意外的情况,一定会帮用户把资源释放掉),不过利用的思想正是对象出作用域,编译器会自动调用对象的析构函数,保证引用的堆空间被正确的释放。

  • 数据段:在程序运行结束后,数据段的数据才会被释放;
  • 堆: 需要手动调用释放函数释放资源(堆严格意义上也属于数据,上面的数据主要指全局和static对象);
  • 栈:** 函数调用结束会自己释放(智能指针基于该思想设计),退出局部作用域,编译器会自动添加销毁局部变量的指令。**
  • 自定义局部作用域:
int main(){
	int a = 10;
	{
	std::vector<int> vec;
	} //这也是一个局部的作用域,出右括号vec将不存在
}

实现一个智能指针:底层是我们经常使用的裸指针,通过构造函数构造一个栈上的对象,在局部对象出作用域前会自动调用对象的析构函数,即就是释放底层裸指针所引用的外部资源。C++11标准委员会将智能指针从Boost库中引用过来。

实现一个不带引用计数的智能指针:

template <typename T>
class CSmartPtr{
public:
CSmartPtr(T *ptr = NULL)
		:mptr(ptr){}
~CSmartPtr(){
	delete mptr;
}

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

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

class A
{
public:
	void func(){ cout << "call A::func" << endl; }
};

//对智能指针的操作最终转成对底层普通指针的操作,当然包括对运算符重载函数的
int main(int argc, char* argv[]){
	CSmartPtr <int> ptr1(new int);
	*ptr1 = 30;//表面看起来是在解引用智能指针,实际上调用operator*,解引用封装的裸指针
	cout << *ptr1 << endl;

	CSmartPtr <A> ptr3(new A());
	(*ptr3).func();
	ptr3->func();//operator->返回的是封装的裸指针,然后裸指针再去调用func

	//智能指针对象调用->运算符重载函数返回一个普通指针,普通指针调用对应的方法
	const CSmartPtr <A> ptr4(new A());
	//(*ptr4).func();
	ptr4->func();
	return 0;
}
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章