C++11新特性 智能指针 unique_ptr shared_ptr weak_ptr 交叉引用

nuique_ptr

unique_ptr在要表达"专属所有权"的语义时使用,即unique_ptr指针永远′拥有"其指向的对象,所以unique_ptr是一个move-only类型,一个unique_ptr指针是无法被复制的,只能将"所有权"在两个unique_ptr指针之间转移,转移完成后原来的unique_ptr将被设为null;
智能指针是比原始指针更智能的类,解决悬空(dangling)指针或多次删除被指向对象,以及资源泄露问题,通常用来确保指针的寿命和其指向对象的寿命一致。智能指针虽然很智能,但容易被误用,智能也是有代价的。

特点

1 .基于排他所有权模式:两个指针不能指向同一个资源。这一块资源只能被一个指针指向
2.由于独占对象的拥有权,所以不提供拷贝构造函数和左值赋值函数重载。浅拷贝构造和浅赋值都是两个对象同时指向一个资源,
深拷贝,深赋值,同样的资源复制了一份,被两个unique对象指向,不行。
3.提供移动构造和移动赋值函数。
4 .为了实现单个对象和一组对象的管理,添加了删除器类型。
5.在容器保存指针是安全。
6.unique_ptr具有->和*运算符重载符,因此它可以像普通指针一样使用。


class PtrInt {
   
private:
	int* pval;
public:
	PtrInt(int x=0):pval(new int(x)){
   
		cout << "Create PtrInt" << this << endl;
	}
	~PtrInt() {
   
		delete pval;
		pval = nullptr;
		cout << "Destroy PtrInt" << this << endl;
	}
	PtrInt(const PtrInt& it) :pval(new int(10)) {
   
		if (it.pval != nullptr) {
   
			*pval = *it.pval;
		}
		cout  << this<< "Copy Create PtrInt" <<&it<< endl;
	}
	PtrInt& operator=(const PtrInt& it) {
   
		if (this != &it) {
   
			delete pval;
			if (it.pval != nullptr) {
   
				pval = new int(*it.pval);
			}
		}
		cout << this << "operator=()" << &it << endl;
		return *this;
	}
	PtrInt(PtrInt&& it) :pval(it.pval) {
   
		it.pval = nullptr;
		cout<<this << "Move Create PtrInt" << &it << endl;
	}
	PtrInt& operator=(PtrInt&& it) {
   
		if (this != &it) {
   
			delete[]pval;
			pval = it.pval;
			it.pval = nullptr;
		}
		cout << this << "Move operatro=()" << &it << endl;
		return *this;
	}
	void SetValue(int x) {
    *pval = x; }
	int GetValue()const {
    return *pval; }
	void Print()const {
   
		if (pval != nullptr) {
   
			cout << *pval << endl;
		}
	}

};


template<class _Ty>
class my_unique_ptr {
   
public:
	using pointer = _Ty*;
	using element_type = _Ty;
private:
	pointer mPtr;
public:
	my_unique_ptr(_Ty* p = nullptr) :mPtr(p){
   }
	//唯一性指针没有拷贝构造和左值赋值
	my_unique_ptr(const my_unique_ptr&) = delete;
	my_unique_ptr& operator=(const my_unique_ptr&) = delete;
	~my_unique_ptr() {
   
		if (mPtr != nullptr) {
   
			delete mPtr;
		}
		mPtr = nullptr;
	}
};

int main() {
   
	unique_ptr<PtrInt>pa(new PtrInt(10));
	pa->Print();
	return 0;
}

在这里插入图片描述
my_unique_ptrpa(new PtrInt(100));
在这里插入图片描述

不允许拷贝构造和赋值

唯一性智能指针不允许拷贝构造:浅拷贝pa pb的mPtr会指向同一个空间,析构时会把同一个地址释放两次,深拷贝就有了两份空间,应该只有一份

my_unique_ptr(const my_unique_ptr&) = delete;

也不允许赋值

my_unique_ptr& operator=(const my_unique_ptr&) = delete;

可以实现移动拷贝构造和移动赋值
移动之后,资源就不是以前的了,强行访问会崩溃

my_unique_ptr(my_unique_ptr&& x) :mPtr(x.mPtr) {
   
		x.mPtr = nullptr;
}
	//pa=move(pb);  //unique_
my_unique_ptr operator=(my_unique_ptr&& other) {
   
		if (this == &other)return *this;
		//my_unique_ptr(move(other)).swap(*this); 与下面三行等价
		delete mPtr;
		mPtr = other.mPtr;
		other.mPtr = nullptr;

		return *this;
}

运算符重载-> () *

在这里插入图片描述
pa是一个对象,访问对象的成员函数用.
为啥可以pa->
-> 都是用在结构体指针,->就是 先解引用,再 . 访问对象成员函数
这里重载了->
pa->Print();
pa.operator->()->Print();
等价

	pointer get()const {
    return mPtr; }
	_Ty& operator*()const {
    return *get(); }
	_Ty* operator->()const {
    return get(); }

在这里插入图片描述

int main() {
   
    unique_ptr<Int>pa(new Int(100));
    
	pa->Print();
	pa.operator->()->Print();
	
	return 0;
}
class Int {
   
	int value;
public:
	Int(int x = 0) :value(x) {
   
		cout << "Create Int " << endl;
	}
	~Int() {
    cout << "Destroy Int " << endl; }
	void SetValue(int x) {
    value = x; }
	int GetValue()const {
   
		return value;
	}
	void Print()const {
    cout << value << endl; }
};


template<class _Ty>
class my_unique_ptr {
   
public:
	using pointer = _Ty*;
	using element_type = _Ty;
private:
	pointer mPtr;
public:
	my_unique_ptr(_Ty* p = nullptr) :mPtr(p){
   }
	my_unique_ptr(const my_unique_ptr&) = delete;
	my_unique_ptr& operator=(const my_unique_ptr&) = delete;
	my_unique_ptr(my_unique_ptr&& x) :mPtr(x.mPtr) {
   
		x.mPtr = nullptr;
	}
	
	~my_unique_ptr() {
   
		if (mPtr != nullptr) {
   
			delete mPtr;
		}
		mPtr = nullptr;
	}
	pointer get()const {
    return mPtr; }
	_Ty& operator*()const {
    return *get(); }
	_Ty* operator->()const {
    return get(); }


};

int main() {
   
    unique_ptr<Int></
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值