c++智能指针(2)

追加一个shared_ptr指针

#include <memory>

using namespace std;

int _tmain(int argc, _TCHAR* argv[])
{
    //===========================
    // 错误 两个只能指针 管理一个已经分配的内存
    //int* p = new int(7);
    //shared_ptr<int> p1(p);
    //shared_ptr<int> p2(p);
    //============================

    //================================
    // 正确做法 
    shared_ptr<int> sp1(new int(7));
    shared_ptr<int> sp2(sp1); //
    //================================

    return 0;
}

 

 

weak_ptr示例

/*
//    使用shred_ptr的主要原因就是避免关注指针指向的资源
//    只能指针将自动释放与不再需要的对象的相关资源
//    但是某些情况下,这种却不是我们需要的。
//    比如 循环引用.两个对象都引用对方。
//    又或者 分享一个对象 但是不占有该对象
//    这个时候可以使用weak_ptr 其实相对shared_ptr 该指针不增加计数
//
*/

#include <iostream>
#include <string>
#include <vector>
#include <memory>

using namespace std;

class Person{
public:
    string name;
    shared_ptr<Person> mother;
    shared_ptr<Person> father;
    vector<shared_ptr<Person>> kids;

    Person(const string& n,
        shared_ptr<Person> m = nullptr,
        shared_ptr<Person> f = nullptr)
        :name(n), mother(m), father(f){
    }

    ~Person(){
        cout << "delete " << name << endl;
    }
};


shared_ptr<Person> initFamily(const string& name)
{
    shared_ptr<Person> mom(new Person(name + "'s mom"));
    shared_ptr<Person> dad(new Person(name + "'s dad"));
    shared_ptr<Person> kid(new Person(name,mom,dad));
    mom->kids.push_back(kid);
    dad->kids.push_back(kid);
    return kid;
}

int _tmain(int argc, _TCHAR* argv[])
{
    shared_ptr<Person> p = initFamily("nico");

    cout << "nico's family exists" << endl;
    cout << "- nico is shared " << p.use_count() << " times" << endl;
    cout << "- name of 1st kid of nico's mom: "
        << p->mother->kids[0]->name << endl;

    p = initFamily("jim");
    cout << "jim's family exists" << endl;

    return 0;
}

 

运行代码结果如下:

nico's family exists
- nico is shared 3 times
- name of 1st kid of nico's mom: nico
jim's family exists
请按任意键继续. . .

实际上我们并没有看到 指针指向资源的释放 这是因为在class Person 中的vector中 使用了shared_ptr 指针增加了资源的计数 所以没有及时释放

 

我们应该将vector这个容器改为weak_ptr  同时在使用上 weak_ptr 需要使用lock() 函数将其提升为shared_ptr

/*
//    使用shred_ptr的主要原因就是避免关注指针指向的资源
//    只能指针将自动释放与不再需要的对象的相关资源
//    但是某些情况下,这种却不是我们需要的。
//    比如 循环引用.两个对象都引用对方。
//    又或者 分享一个对象 但是不占有该对象
//    这个时候可以使用weak_ptr 其实相对shared_ptr 该指针不增加计数
//
*/

#include <iostream>
#include <string>
#include <vector>
#include <memory>

using namespace std;


class Person {
public:
    string name;
    shared_ptr<Person> mother;
    shared_ptr<Person> father;
    vector<weak_ptr<Person>> kids; //weakpointer!!!
    Person(const string& n,
        shared_ptr<Person> m = nullptr,
        shared_ptr<Person> f = nullptr)
        : name(n), mother(m), father(f) {
    }
    ~Person() {
        cout << "delete " << name << endl;
    }
};

shared_ptr<Person> initFamily(const string& name)
{
    shared_ptr<Person> mom(new Person(name + "'s mom"));
    shared_ptr<Person> dad(new Person(name + "'s dad"));
    shared_ptr<Person> kid(new Person(name,mom,dad));
    mom->kids.push_back(kid);
    dad->kids.push_back(kid);
    return kid;
}

int _tmain(int argc, _TCHAR* argv[])
{
    shared_ptr<Person> p = initFamily("nico");

    cout << "nico's family exists" << endl;
    cout << "- nico is shared " << p.use_count() << " times" << endl;
    cout << "- name of 1st kid of nico's mom: "
        << p->mother->kids[0].lock()->name << endl;

    p = initFamily("jim");
    cout << "jim's family exists" << endl;

    return 0;
}

 

运行结果如下 

nico's family exists
- nico is shared 1 times
- name of 1st kid of nico's mom: nico
delete nico
delete nico's dad
delete nico's mom
jim's family exists
delete jim
delete jim's dad
delete jim's mom
请按任意键继续. . .

 

可以看到 资源正确释放

代码 改编自 C++标准库——自学教程与参考手册 英文第二版

posted on 2014-08-31 17:25  itdef  阅读(257)  评论(0编辑  收藏  举报

导航