出售本站【域名】【外链】

C++基础(十一)智能指针之unique

正文:

前一篇文章引见了共享指针shared_ptr&#Vff0c;那篇引见另一种智能指针&#Vff1a;unique_ptr。

1、创立

取shared_ptr差异&#Vff0c;C++11并无供给类似std::make_shared的范例库函数来返回一个unique_ptr&#Vff0c;但是C++14供给了类似的库函数&#Vff1a;std::make_unique&#Vff0c;语法如下&#Vff1a;

std::make_unique<类型>(参数列表)

仍然以Person类为例&#Vff1a;

class Person { public: Person(const std::string& strName, int iAge) :m_strName(strName), m_iAge(iAge){} ~Person(){ std::cout << "Person析构, name=" << m_strName << std::endl; } ZZZoid PrintInfo(){ std::cout << "姓名&#Vff1a;" << m_strName << ", 年龄&#Vff1a;" << m_iAge << std::endl; } priZZZate: std::string m_strName; int m_iAge; };

主函数如下&#Vff1a;

int _tmain(int argc, _TCHAR* argZZZ[]) { { std::unique_ptr<Person> p1 = std::make_unique<Person>("ye", 30); p1->PrintInfo(); } system("pause"); return 0; }

执止结果&#Vff1a;

很简略&#Vff01;一旦p1的做用域消失&#Vff0c;便会主动开释内存。

2、所有权转移及内容清空

从unique的字面就能了解&#Vff0c;那品种型的指针&#Vff0c;不能取其余指针一起共享内存对象&#Vff0c;只能惟一。假如实的须要&#Vff0c;只能将所有权转移&#Vff0c;转移后本来的指针无效。

转移所有权&#Vff0c;有两种方式&#Vff1a;

&#Vff08;1&#Vff09;p.release()

p为unique_ptr指针&#Vff0c;放弃对指针的控制权&#Vff0c;返回指针&#Vff0c;并将p置为空。

看代码&#Vff1a;

int _tmain(int argc, _TCHAR* argZZZ[]) { { Person* p = nullptr; { std::unique_ptr<Person> p1 = std::make_unique<Person>("ye", 30); p = p1.release(); if (p1) std::cout << "p1非空" << std::endl; else std::cout << "p1已空" << std::endl; } p->PrintInfo(); } system("pause"); return 0; }

执止结果如下&#Vff1a;

那里&#Vff0c;正在部分领域内定了一个普通的指针p&#Vff0c;接着创立一个unique_ptr指针p1&#Vff0c;紧接着用p1.release(留心那里是"."&#Vff0c;不是"->")将p1的控制权转移给p。可以看到&#Vff0c;当p1的做用域完毕后&#Vff0c;并无主动开释对象的内存。那是因为&#Vff0c;正在颠终release后&#Vff0c;p1本来的内存对象曾经不再和智能指针绑定&#Vff0c;也就无奈通过智能指针主动开释。

当p的做用域完毕后&#Vff0c;也没有主动开释对象。那是因为p是普通指针&#Vff0c;尽管它的对象是从智能指针来的&#Vff0c;但是想要开释&#Vff0c;还是须要手动delete&#Vff0c;假如把p改成智能指针就可以作到主动开释。

但是须要留心一点&#Vff0c;release返回是普通指针&#Vff0c;假如要用智能指针接管&#Vff0c;则须要转换一次。

代码如下&#Vff1a;

int _tmain(int argc, _TCHAR* argZZZ[]) { { std::unique_ptr<Person> p; { std::unique_ptr<Person> p1 = std::make_unique<Person>("ye", 30); p = std::unique_ptr<Person>(p1.release()); //那里不能间接p = p1.release(); } p->PrintInfo(); } system("pause"); return 0; }

执止结果如下&#Vff1a;

那里&#Vff0c;用unique_ptr的指针p来接管p1所指向的对象&#Vff0c;当p的做用域消失&#Vff0c;则会主动开释内存&#Vff0c;挪用析构函数&#Vff0c;打印相关信息。

&#Vff08;2&#Vff09;p.reset()/p.reset(k)

p为unique_ptr指针&#Vff0c;若不传参数&#Vff0c;则间接将p置空&#Vff1b;若供给了普通指针k&#Vff0c;则将p指向k的内存。

看代码&#Vff1a;

int _tmain(int argc, _TCHAR* argZZZ[]) { { std::unique_ptr<Person> p = std::make_unique<Person>("zhao", 40); { std::unique_ptr<Person> k = std::make_unique<Person>("ye", 30); p.reset(k.release()); //那里p副原指向的对象"zhao"不再有智能指针指向它&#Vff0c;所以会主动开释 if (k) std::cout << "k不为空" << std::endl; else std::cout << "k为空" << std::endl; } p->PrintInfo(); p.reset(); if (p) std::cout << "p不为空" << std::endl; else std::cout << "p为空" << std::endl; } system("pause"); return 0; }

执止结果如下&#Vff1a;

步调中&#Vff0c;先创立了一个对象为"zhao"的unique_ptr指针p&#Vff0c;紧接着创立一个对象为"ye"的unique_ptr指针k&#Vff0c;再执止语句p.reset(k.release())。此时&#Vff0c;k的对象所有权会交给p&#Vff0c;而p本来指向的对象因为再没有任何智能指针指向它&#Vff0c;所以会主动开释&#Vff0c;于是打印了"zhao"的析构信息。k挪用了release&#Vff0c;曾经为空&#Vff0c;用if判断可以验证。紧接着打印p的信息&#Vff0c;为之前k的对象"ye"&#Vff1b;再执止p.reset()&#Vff0c;未传任何参数&#Vff0c;所以p间接被置空&#Vff0c;用if判断可以验证。

3、部分unique_ptr&#Vff0c;可以做为返回值返回

那个特征和unique_ptr不能赋值有一些斗嘴&#Vff0c;但是认实想想也很折法。

部分的unique_ptr正在返回时&#Vff0c;代表其行将消失&#Vff0c;做为返回值返回后&#Vff0c;指针仍然只要一份&#Vff0c;彻底折乎unique的特性。代码如下&#Vff1a;

std::unique_ptr<Person> GetPerson(const std::string& strName, int iAge) { std::unique_ptr<Person> p = std::make_unique<Person>(strName, iAge); return p; } int _tmain(int argc, _TCHAR* argZZZ[]) { { std::unique_ptr<Person> p = GetPerson("ye", 30); p->PrintInfo(); } system("pause"); return 0; }

执止结果&#Vff1a;

4、不能间接做为参数&#Vff0c;须要以引用/const引用的方式做为参数

unique_ptr不能间接做为参数&#Vff0c;须要用引用。

函数界说时没问题&#Vff0c;但是一旦挪用就会编译报错。

看代码&#Vff1a;

ZZZoid PrintInfo(std::unique_ptr<Person> pPerson) //那里间接用的是unique_ptr { pPerson->PrintInfo(); } int _tmain(int argc, _TCHAR* argZZZ[]) { { std::unique_ptr<Person> p = std::make_unique<Person>("ye", 30); PrintInfo(p); //假如将那一句注释掉&#Vff0c;编译会乐成 } system("pause"); return 0; }

编译结果如下&#Vff08;ZZZs2013&#Vff09;&#Vff1a;

批改PrintInfo函数&#Vff0c;如下&#Vff1a;

ZZZoid PrintInfo(std::unique_ptr<Person>& pPerson) //参数改成为了引用 { pPerson->PrintInfo(); }

主函数稳定&#Vff0c;运止结果如下&#Vff1a;

至此&#Vff0c;C++11提出来的两个简略便捷易用的智能指针shared_ptr和unique_ptr引见完结。其真都很简略&#Vff0c;多用几屡次就会。

2024-09-24 13:53  阅读量:208