一:unique_ptr简介
独占式的概念(专属所有权):同一时刻只能有一个 unique_ptr 指针指向这个对象(这块内存);
当这个unique_ptr被销毁时候,它所指向的对象也被销毁
格式
unique_ptr<指向的对象类型> 只能指针变量名;
<1>常规初始化( unique_ptr 和 new 配合)
int main()
{
unique_ptr<int> pi; //可以指向int对象的一个空智能指针
if (pi == nullptr)
{
cout << "pi目前还是空指针" << endl;
}
unique_ptr<int> pi2(new int(100)); //此时pi2指向一个值为100的int对象
return 0;
}
<2>make_unique函数
C++11中没有,C++14才有的make_unique,不支持指定的删除器语法,如果不用删除器,建议优先使用,更高的性能。
int main()
{
unique_ptr<int> p1 = make_unique<int>(100);
auto p2 = make_unique<int>(200);
unique_ptr<int> pi2(new int(105)); //前边不能简写为auto;
return 0;
}
二:unique_ptr的常规操作
<1>unique_ptr不支持的操作(独占式)
int main()
{
unique_ptr<string> ps1(new string("I Love China"));
unique_ptr<string> ps2(ps1); //该智能指针不支持拷贝操作(定义时初始化)
unique_ptr<string> ps3 = ps1; //该智能指针不支持拷贝操作 和赋值 (定义时初始化)
unique_ptr<string> ps4;
ps4 = ps1; //独占式智能指针不支持赋值操作
return 0;
}
<2>移动语义
int main()
{
unique_ptr<string> ps1(new string("I Love China"));
unique_ptr<string> ps2 = std::move(ps1); // 移动完后,ps1为空,ps2指向原来的ps1所指对象
return 0;
}
<3>release()
放弃对这个指针的控制权(切断了智能指针和所指向对象之间的联系)
返回裸指针,并将该智能指针置空。返回的这个裸指针我们可以手工 delete 来释放,也可以用来初始化另外一个智能指针,或者给另外一个智能指针赋值。
int main()
{
unique_ptr<string> ps1(new string("I Love China"));
unique_ptr<string> ps2(ps1.release());
if (ps1 == nullptr)
{
cout << "ps1被置空" << endl;
}
ps2.release(); //导致内存泄漏
string* temp = ps2.release(); //suto *temp = ps2.release();
delete temp; //人工(手工)delete释放
return 0;
}
<4>reset()
reset()不带参数的情况:释放智能指针所指向的对象,并将智能指针置空。
int main()
{
unique_ptr<string> ps1(new string("I Love China1"));
ps1.reset();
if (ps1 == nullptr)
{
cout << "ps1被置空" << endl;
}
return 0;
}
reset()带参数的情况:释放智能指针所指向的对象,并让该智能指针指向新的对象。
int main()
{
unique_ptr<string> ps1(new string("I Love China1"));
unique_ptr<string> ps2(new string("I Love China2"));
ps1.reset(ps2.release()); // reset释放ps1指向的对象内存,让ps1指向ps2所指向的内存,同时ps2被置空
ps1.reset(new string("I Love China3"));
return 0;
}
<5>=nullptr
释放智能指针所指向的对象,并将智能指针置空
int main()
{
unique_ptr<string> ps1(new string("I Love China1"));
ps1 = nullptr; // 释放ps1指向的对象,并将ps1置空
return 0;
}
<6>指向一个数组
int main()
{
unique_ptr<int[]> ptarray(new int[10]); // 注意:这里的数组要跟上[]
ptarray[0] = 12;
ptarray[1] = 24;
return 0;
}
这里不要忘记A[], 否则如果有自己的析构函数,则会报异常
unique_ptr<A[]> ptrarray(new A[10]); //vector, string,
<7>get()
返回智能指针中保存的裸指针,考虑到有些函数参数需要的是内置裸指针(第三方库,我们更改不了代码),所以引入该函数
int main()
{
unique_ptr<string> ps1(new string("I Love China1"));
string* ps = ps1.get();
*ps = "This is a test!";
delete ps; // 不可以,否则产生不可预料的后果
return 0;
}
<8>*解引用
获取该智能指针所指向的对象,可以直接操作
int main()
{
unique_ptr<string> ps2(new string("I Love China"));
*ps2 = "This is a test!";
unique_ptr<int> pt1(new int(100));
*pt1 = 200;
unique_ptr<int[]> pt2(new int[10]); // 对于定的内容是数组,是没有*解引用运算符的
*pt2[0] = 100; //报错!
return 0;
}
<9>swap()
交换两个智能指针所指向的对象
int main()
{
unique_ptr<string> ps1(new string("I Love China1"));
unique_ptr<string> ps2(new string("I Love China2"));
std::swap(ps1, ps2);
ps1.swap(ps2);
return 0;
}
<10>智能指针名字作为判断条件
int main()
{
unique_ptr<string> ps1(new string("I Love China1"));
if (ps1) //if(ps1 != nullptr)
{
//若ps1指向一个对象,那么这个就成立
cout << "ps1不为空" << endl;
}
else
{
cout << "ps1为空" << endl;
}
ps1.reset();
if (ps1)
{
//若ps1指向一个对象,那么这个就成立
cout << "ps1不为空" << endl;
}
else
{
cout << "ps1为空" << endl;
}
return 0;
}
<11>转换成shared_ptr类型
如果 unique_ptr 为右值,就可以将它赋值给 shared_ptr。
因为 shared_ptr 包含一个显式构造函数,可用于将右值 unqiue_ptr 转换成 shared_ptr。
shared_ptr将接管原来的unique_ptr。
auto myfunc()
{
return unique_ptr<string>(new string("I Love China")); //这是个右值 (临时对象都是右值)
}
int main()
{
shared_ptr<string> pss1 = myfunc(); // 这里会创建控制块, unique_ptr没有控制块
unique_ptr<string> ps2(new string("I Love China"));
shared_ptr<string> pss2 = std::move(ps2); //左值转右值, 执行后ps2为空,pss2就是shared_ptr
cout << sizeof(pss1) << endl;
cout << sizeof(ps2) << endl;
return 0;
}