c++面试四--智能指针原理补充 1.1w字

深入掌握C++智能指针_深入掌握c++智能指针 大秦坑王-CSDN博客

C++11 - 右值引用_大秦坑王 右值引用+引用折叠原理-CSDN博客

一、基本原理

        智能指针的基本原理,就是利用栈上的对象出作用域会自动析构这么一个特点,把资源释放的代码全部放在这个析构函数中执行,就达到了所谓的智能指针。

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

int main()
{
	CSmartPtr<int> ptr(new int);
	/*其它的代码...*/

	/*由于ptr是栈上的智能指针对象,不管是函数正常执行完,还是运行过程中出现
	异常,栈上的对象都会自动调用析构函数,在析构函数中进行了delete
	操作,保证释放资源*/
	return 0;
}

上面这段代码就是一个非常简单的智能指针,主要用到了这两点:
1)智能指针体现在把裸指针进行了一次面向对象的封装,在构造函数中初始化资源地址,在析构函数中负责释放资源
2)利用栈上的对象出作用域自动析构这个特点,在智能指针的析构函数中保证释放资源

所以,智能指针一般都是定义在栈上的,曾经有一个面试问题,问“能不能在堆上定义智能指针?”,如这段代码CSmartPtr *p = new CSmartPtr(new int);大家应该能看出来,这里定义的p虽然是智能指针类型,但它实质上还是一个裸指针,因此p还是需要进行手动delete,又回到了最开始裸指针我们面临的问题。

        二、智能指针要做到和裸指针相似,还得提供裸指针常见的*和->两种运算符的重载函数,使用起来才真正的和裸指针一样

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

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

	T* operator->() { return mptr; }
	const T* operator->()const { return mptr; }
private:
	T *mptr;
};
int main()
{
	CSmartPtr<int> ptr(new int);

	*ptr = 20;
    // ->   底层实际是  ( ptr.operator->() )->test();    test() 是方法
	cout << *ptr << endl;
	return 0;
}

三、智能指针的构造函数

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

        这个main函数运行,代码直接崩溃,问题出在默认的拷贝构造函数做的是浅拷贝,两个智能指针都持有一个new int资源,ptr2先析构释放了资源,到ptr1析构的时候,就成了delete野指针了,造成程序崩溃。所以这里引出来智能指针需要解决的两件事情:

        怎么解决智能指针的浅拷贝问题
        多个智能指针指向同一个资源的时候,怎么保证资源只释放一次,而不是每个智能指针都释放一次,造成代码运行不可预期的严重后果

         之前的深拷贝构造函数,在智能指针中不行,因为是重新开辟了一块资源给ptr2,ptr1和ptr2是两块内存,可是用户人为是ptr1和ptr2指向同一块内存。

将怎么解决浅拷贝问题可以分为  不带引用计数的智能指针和带引用计数的智能指针

C++库中提供的不带引用计数的智能指针主要包括:auto_ptr,scoped_ptr,unique_ptr。

        使用 explicit 关键字可以避免一些意外的隐式类型转换,提高代码的安全性和可读性。通常情况下,如果构造函数只接受一个参数,并且不希望它被隐式调用,就应该将其声明为 explicit

四、auto_ptr,scoped_ptr,unique_ptr

一、auto_ptr在拷贝构造中,将原有的智能指针置为nullptr,然后将对象赋值给新的智能指针。

二、scoped_ptr 将拷贝构造函数和赋值操作删除或私有化
template<class T> class scoped_ptr // noncopyable
{
private:
    T * px;
	
	/*
	私有化拷贝构造函数和赋值函数,这样scoped_ptr的智能指针
	对象就不支持这两种操作,从根本上杜绝浅拷贝的发生
	*/
    scoped_ptr(scoped_ptr const &);
    scoped_ptr & operator=(scoped_ptr const &);
 
    typedef scoped_ptr<T> this_type;
		
	/*
	私有化逻辑比较运算符重载函数,不支持scoped_ptr的
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值