hello_vzjw

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)    收藏  举报

导航