智能指针
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></
最低0.47元/天 解锁文章
3万+

被折叠的 条评论
为什么被折叠?



