C++智能指針(2)—— unique_ptr
- 1、unique_ptr
- 2、右值引用
- 3、bool類型的重載
- 4、自己重寫部分源碼
1、unique_ptr
①不能使用同一個裸指針指派,或使用同一個裸指針初始化多個unique ptr
②不允許隐式構造
void text01()
{
int* p = new int(10);
unique_ptr<int> u_p=p;//報錯,不允許隐式構造
unique_ptr<int> u_p1(p);
cout << *p << endl;
cout << u_p << endl;
}
int main()
{
text01();
return 0;
}
③不允許拷貝構造,不允許等号運算符重載
void text01()
{
int* p = new int(10);
unique_ptr<int> u_p(p);
unique_ptr<int> u_p1(p);
u_p1 = u_p;//不允許等号運算符重載,會報錯
cout << *p << endl;
cout << u_p << endl;
}
int main()
{
text01();
return 0;
}
但是為什麼下面的程式卻能夠通過?
unique_ptr<int> fun(unique_ptr<int>& ptr)
{
cout << *ptr << endl;
int* p = new int(9);
return unique_ptr<int>(p);
}
void text01()
{
int* p = new int(10);
unique_ptr<int>u_p(p);
unique_ptr<int>u_p2(fun(u_p));//有拷貝構造的過程,但是能夠運作通過
cout << *u_p2 << endl;
}
int main()
{
text01();
return 0;
}
原因:
存在右值引用的等号運算符,右值引用的拷貝構造,就可以,而普通對象不能放在右值引用的拷貝構造或者等号運算符中。
2、右值引用
用來引用即将死亡的對象
void text02()
{
const int& a = 10;
int&& b = 10;
//上面兩行等價,如果隻是int& a = 10,會報錯,原因是a是一個不可取位址的量,10會産生臨時量,具有常屬性,是以對a前面加上const
const int c = 10;
const int& d = c;
int&& e = c;//這行還會報錯,是以右值引用并不是用來引用常量,而是臨時對象
}
3、bool類型的重載
void text01()
{
int* p = new int(10);
unique_ptr<int>u_p(p);
if (u_p)//将指針放在if的括号内,并不會出錯
{
}
}
4、自己重寫部分源碼
template <typename T>
class Munique_ptr
{
public:
//構造
explicit Munique_ptr(T* ptr = nullptr)
:_ptr(ptr)//explicit用來防止隐式構造
{
}
//拷貝構造
Munique_ptr(Munique_ptr& src) = delete;
//等号運算符重載
Munique_ptr operator=(Munique_ptr& src) = delete;
//移動拷貝構造
Munique_ptr(Munique_ptr&& src)
:_ptr(src.release())
{
}
//移動等号運算符重載
Munique_ptr& operator=(Munique_ptr&& src)
{
_ptr = src.release();
}
~Munique_ptr()
{
delete _ptr;
//unique_ptr的源碼中有删除器,進而根據請款選擇delete還是delete[],而本篇不妨寫删除器部分
}
T* release()
{
T* tmp = _ptr;
_ptr = nullptr;
return tmp;
}
void reset()
{
delete _ptr;
_ptr = nullptr;
}
T& operator*()
{
return *_ptr;
}
T* operator->()
{
return _ptr;
}
operator bool()
{
return _ptr != NULL;
}
private:
T* _ptr;
};