c++ 智能指针—— c++复习(八)
在c++复习(一)中,我们有接触c++内存管理的知识。我们通过new和delete来配对分配和释放动态内存。忘记delete将导致“内存泄漏”;忘记指针置空将导致野指针;重复delete将导致自由空间遭到破坏。所以呢,就使得我们在管理内存的时候经常会出现一些问题。而这也正好是c++标准库中智能指针可以解决的问题。
auto_ptr
class Test{
private:
string str;
public:
Test(string s){
str = s;
cout<<"Test create\n";
}
~Test(){
cout<<"Test delete:"<<str<<endl;
}
string& getStr(){
return str;
}
void setStr(string s){
str = s;
}
void print(){
cout<<str<<endl;
}
};
int main(int argc,const char * argv[]){
auto_ptr<Test>ptest(new Test("123"));
ptest->setStr("hello");
ptest->print();
ptest.get()->print();//get获取原始指针
ptest->getStr() += "world!";
(*ptest).print();
ptest.reset(new Test("123"));//reset()重新绑定指向的对象,而原来的对象则会释放
ptest->print();
auto_ptr<Test>ptest2(new Test("456"));
auto_ptr<Test>ptest3(new Test("789"));
ptest2 = ptest3;//ptest2会接管ptest3原来的内存管理,ptest3会变为空指针。
ptest2->print();
if (ptest3.get() == NULL) {//判断智能指针是否为空不能使用if(ptest3 == NULL)
cout<<"ptest3 = NULL"<<endl;
}
auto_ptr<Test>ptest4(new Test("10 11"));
ptest4.release();//没有调用析构函数,只是将智能指针置空,内存并没有释放。如果我们想要在中途释放资源,而不是等到智能指针被析构时才释放,我们应该使用ptest4->reset();
return 0;
}
unique_ptr
unique_ptr和auto_ptr用法很相似,不过不能使用两个智能指针赋值操作,应该使用std::move;但是它可以直接使用if(ptest == NULL)来判断是否为空指针;release、get、reset等用法也和auto_ptr一致,使用函数的返回值时,可以直接使用=,当把它作为参数(值传递)时,也应该使用std::move()。它还增加了swap用于交换两个智能指针的值。
unique_ptr<Test>fun(){
return unique_ptr<Test>(new Test("uniquePtr"));
}
int main(int argc,const char * argv[]){
//unique_ptr
unique_ptr<Test> ptest(new Test("123"));
unique_ptr<Test> ptest2(new Test("456"));
ptest->print();
ptest2 = move(ptest);//不能直接ptest2 = ptest;
if (ptest == NULL) {
cout<<"ptest = NULL\n";
}
Test* p = ptest2.release();
p->print();
ptest.reset(p);
ptest->print();
ptest2 = fun();//这里可以使用=,因为使用了移动构造函数
ptest2->print();
return 0;
}
share_ptr
sahre_ptr使用引用计数的原则,可以通过use_count()来查看引用计数额的个数。每使用一次release,引用计数就减1,当计数等于0时,资源会被释放。有点类似oc的ARC。
int main(int argc,const char * argv[]){
shared_ptr<Test>ptest(new Test("123"));
shared_ptr<Test>ptest2(new Test("456"));
cout<<ptest2->getStr()<<endl;
cout<<ptest2.use_count()<<endl;
ptest = ptest2;//"456"引用次数加一,"123"销毁
ptest->print();
cout<<ptest2.use_count()<<endl;
cout<<ptest.use_count()<<endl;
ptest.reset();
ptest2.reset();
cout<<"end\n";
return 0;
}
weak_ptr
weak_ptr是用来解决share_ptr相互引用时的死锁问题。如果说两个share_ptr相互引用,那么这两个指针的引用计数永远不可能为0,资源永远不会释放。所以当遇到这种情况的时候,将其中一个智能指针改成weak_ptr就可以了。
posted on 2016-05-06 10:06 hello_vzjw 阅读(124) 评论(0) 收藏 举报
浙公网安备 33010602011771号