shared_ptr使用

shared_ptr使用

分类: C++ boost 39人阅读 评论(0) 收藏 举报

1.get() 返回对象指针;use_count() 返回对象的引用计数

  1. #include <iostream>   
  2. #include <tr1/memory>    
  3.   
  4. using namespace std;  
  5. using std::tr::shared_ptr;  
  6.   
  7. class Foo  
  8. {  
  9. public:  
  10.     void print()  
  11.     {  
  12.         cout << "foo::print" << endl;  
  13.     }  
  14. };  
  15.   
  16. /* When sp2 is created, sp1 increments the reference counter. 
  17.  * When the two shared pointer objects get out of scope, the last 
  18.  * one that is destroyed will release the resource. 
  19.  * 
  20.  * output: 
  21.  * foo::print 
  22.  * sp1 pointer: 0x90a7008 
  23.  * foo::print 
  24.  * sp1 pointer: 0x90a7008 
  25.  * sp2 pointer: 0x90a7008 
  26.  * counter sp1: 2 
  27.  * counter sp2: 2 
  28.  */  
  29. int main()  
  30. {  
  31.     shared_ptr<Foo> sp1(new Foo);  
  32.     sp1->print();  
  33.     cout << "sp1 pointer: " << sp1.get() << endl;  
  34.   
  35.     shared_ptr<Foo> sp2(sp1);  
  36.     sp2->print();  
  37.   
  38.     cout << "sp1 pointer: " << sp1.get() << endl;  
  39.     cout << "sp2 pointer: " << sp2.get() << endl;  
  40.     cout << "counter sp1: " << sp1.use_count() << endl;  
  41.     cout << "counter sp2: " << sp2.use_count() << endl;  
  42.   
  43.     return 0;  
  44. }  
#include <iostream>
#include <tr1/memory> 

using namespace std;
using std::tr::shared_ptr;

class Foo
{
public:
    void print()
    {
        cout << "foo::print" << endl;
    }
};

/* When sp2 is created, sp1 increments the reference counter.
 * When the two shared pointer objects get out of scope, the last
 * one that is destroyed will release the resource.
 *
 * output:
 * foo::print
 * sp1 pointer: 0x90a7008
 * foo::print
 * sp1 pointer: 0x90a7008
 * sp2 pointer: 0x90a7008
 * counter sp1: 2
 * counter sp2: 2
 */
int main()
{
    shared_ptr<Foo> sp1(new Foo);
    sp1->print();
    cout << "sp1 pointer: " << sp1.get() << endl;

    shared_ptr<Foo> sp2(sp1);
    sp2->print();

    cout << "sp1 pointer: " << sp1.get() << endl;
    cout << "sp2 pointer: " << sp2.get() << endl;
    cout << "counter sp1: " << sp1.use_count() << endl;
    cout << "counter sp2: " << sp2.use_count() << endl;

    return 0;
}

2.相比较shared_ptr,auto_ptr在赋值与别人后,是放弃对象引用的。

  1. #include <iostream>   
  2. #include <tr1/memory>   
  3.   
  4. using namespace std;  
  5. using std::tr1::shared_ptr;  
  6.   
  7. class Foo  
  8. {   
  9. public:  
  10.     void print()  
  11.     {  
  12.         cout << "foo::print" << endl;  
  13.     }   
  14. };  
  15.   
  16. /* The next sample shows a shared_ptr created from an auto_ptr object. The auto pointer gives up the ownership of the resource,  
  17.  * resetting its wrapped pointer to NULL.  
  18.  *  
  19.  * output:  
  20.  * foo::print  
  21.  * ap1 pointer: 0x99b8008  
  22.  * foo::print  
  23.  * ap1 pointer: 0  
  24.  * sp1 pointer: 0x99b8008  
  25.  */  
  26. int main()   
  27. {   
  28.     auto_ptr<Foo> ap1(new Foo);  
  29.     ap1->print();   
  30.     cout << "ap1 pointer: " << ap1.get() << endl;  
  31.   
  32.     shared_ptr<Foo> sp1(ap1); // 注意这里是shared_ptr   
  33.     sp1->print();   
  34.     cout << "ap1 pointer: " << ap1.get() << endl;  
  35.     cout << "sp1 pointer: " << sp1.get() << endl;  
  36.   
  37.     return 0;   
  38. }  
#include <iostream>
#include <tr1/memory>

using namespace std;
using std::tr1::shared_ptr;

class Foo
{ 
public:
    void print()
    {
        cout << "foo::print" << endl;
    } 
};

/* The next sample shows a shared_ptr created from an auto_ptr object. The auto pointer gives up the ownership of the resource, 
 * resetting its wrapped pointer to NULL. 
 * 
 * output: 
 * foo::print 
 * ap1 pointer: 0x99b8008 
 * foo::print 
 * ap1 pointer: 0 
 * sp1 pointer: 0x99b8008 
 */
int main() 
{ 
    auto_ptr<Foo> ap1(new Foo);
    ap1->print(); 
    cout << "ap1 pointer: " << ap1.get() << endl;

    shared_ptr<Foo> sp1(ap1); // 注意这里是shared_ptr
    sp1->print(); 
    cout << "ap1 pointer: " << ap1.get() << endl;
    cout << "sp1 pointer: " << sp1.get() << endl;

    return 0; 
}
3.在shared_ptr构造函数中,行参指定构造对象和析构对象的函数
  1. #include <iostream>   
  2. #include <tr1/memory>    
  3.   
  4. using namespace std;  
  5. using std::tr1::shared_ptr;  
  6.   
  7. class Foo   
  8. {   
  9. public:  
  10.     void print()  
  11.     {   
  12.         cout << "foo::print" << endl;  
  13.     }   
  14. };   
  15.   
  16. class FooHandler   
  17. {   
  18. public:   
  19.     static Foo* alloc()  
  20.     {  
  21.         Foo* f = new Foo;   
  22.         cout << "a new foo was created" << endl;  
  23.         return f;  
  24.     }  
  25.     static void free(Foo* f)  
  26.     {   
  27.         delete f;   
  28.         cout << "foo destroyed" << endl;  
  29.     }   
  30. };  
  31.   
  32. /*  
  33.  * Each time a new object is created or destroyed, a message is printed in the output window (for simplicity, you will ignore the copy  
  34.  * construction or assignment). Function FooHandler::free can be provided as a delete to the shared_ptr constructor. As a result,  
  35.  * when the resource is deleted a message is printed in the output window (you have to run in debugger to see it).  
  36.  *  
  37.  * output:  
  38.  * a new foo was created  
  39.  * foo::print  
  40.  * foo destroyed  
  41.  */  
  42. int main()  
  43. {  
  44.     shared_ptr<Foo> ptr(FooHandler::alloc(), FooHandler::free);   
  45.     ptr->print();  
  46.   
  47.     return 0;   
  48. }  
#include <iostream>
#include <tr1/memory> 

using namespace std;
using std::tr1::shared_ptr;

class Foo 
{ 
public:
    void print()
    { 
        cout << "foo::print" << endl;
    } 
}; 

class FooHandler 
{ 
public: 
    static Foo* alloc()
    {
        Foo* f = new Foo; 
        cout << "a new foo was created" << endl;
        return f;
    }
    static void free(Foo* f)
    { 
        delete f; 
        cout << "foo destroyed" << endl;
    } 
};

/* 
 * Each time a new object is created or destroyed, a message is printed in the output window (for simplicity, you will ignore the copy 
 * construction or assignment). Function FooHandler::free can be provided as a delete to the shared_ptr constructor. As a result, 
 * when the resource is deleted a message is printed in the output window (you have to run in debugger to see it). 
 * 
 * output: 
 * a new foo was created 
 * foo::print 
 * foo destroyed 
 */
int main()
{
    shared_ptr<Foo> ptr(FooHandler::alloc(), FooHandler::free); 
    ptr->print();

    return 0; 
}
4.get() 返回对象指针,使用->调用成员函数
  1. #include <iostream>   
  2. #include <tr1/memory>    
  3.   
  4. using namespace std;  
  5. using std::tr1::shared_ptr;  
  6.   
  7. class Foo  
  8. {  
  9. public:  
  10.     void print()  
  11.     {  
  12.         cout << "foo::print" << endl;  
  13.     }   
  14. };  
  15.   
  16. /*  
  17.  * Function get() returns the wrapped pointer to the resource (basically identical to operator-> and available for compatibility  
  18.  * with auto_ptr).  
  19.  *  
  20.  * output:  
  21.  * foo::print  
  22.  */   
  23. int main()  
  24. {  
  25.     shared_ptr<Foo> sp(new Foo);  
  26.     Foo* f = sp.get();  
  27.     if (f != NULL)  
  28.         f->print();  
  29.   
  30.     return 0;  
  31. }  
#include <iostream>
#include <tr1/memory> 

using namespace std;
using std::tr1::shared_ptr;

class Foo
{
public:
    void print()
    {
        cout << "foo::print" << endl;
    } 
};

/* 
 * Function get() returns the wrapped pointer to the resource (basically identical to operator-> and available for compatibility 
 * with auto_ptr). 
 * 
 * output: 
 * foo::print 
 */ 
int main()
{
    shared_ptr<Foo> sp(new Foo);
    Foo* f = sp.get();
    if (f != NULL)
        f->print();

    return 0;
}
5.get() 返回对象指针,if判断是否为null
  1. #include <iostream>   
  2. #include <tr1/memory>    
  3. #include <string>   
  4.   
  5. using namespace std;  
  6. using std::tr1::shared_ptr;  
  7.   
  8. /* Class shared_ptr defines a bool operator that allows shared pointers to be used in boolean expressions.  
  9.  * With auto_ptr, that is not possible; you have to use function get() to access the internal pointer and check it against NULL.  
  10.  */  
  11. class PtrUtil  
  12. {  
  13. public:  
  14.     static void is_empty(shared_ptr<string>& ptr)  
  15.     {  
  16.         ptr != NULL ? cout << "not empty" << endl  
  17.                     : cout << "is empty" << endl;  
  18.     }  
  19. };  
  20.   
  21. /* 
  22. * output: 
  23. * is empty 
  24. * not empty 
  25. */  
  26. int main()  
  27. {  
  28.     shared_ptr<string> sp1;  
  29.     shared_ptr<string> sp2(new string("demo"));  
  30.     PtrUtil::is_empty(sp1);  
  31.     PtrUtil::is_empty(sp2);  
  32.   
  33.     return 0;  
  34. }  
#include <iostream>
#include <tr1/memory> 
#include <string>

using namespace std;
using std::tr1::shared_ptr;

/* Class shared_ptr defines a bool operator that allows shared pointers to be used in boolean expressions. 
 * With auto_ptr, that is not possible; you have to use function get() to access the internal pointer and check it against NULL. 
 */
class PtrUtil
{
public:
    static void is_empty(shared_ptr<string>& ptr)
    {
        ptr != NULL ? cout << "not empty" << endl
                    : cout << "is empty" << endl;
    }
};

/*
* output:
* is empty
* not empty
*/
int main()
{
    shared_ptr<string> sp1;
    shared_ptr<string> sp2(new string("demo"));
    PtrUtil::is_empty(sp1);
    PtrUtil::is_empty(sp2);

    return 0;
}
6.swap() 交换两个shared_ptr所指向的对象
  1. #include <iostream>   
  2. #include <tr1/memory>   
  3. #include <string>   
  4.   
  5. using namespace std;  
  6. using std::tr1::shared_ptr;  
  7.   
  8. /* Class shared_ptr defines a bool operator that allows shared pointers to be used in boolean expressions. 
  9.  * With auto_ptr, that is not possible; you have to use function get() to access the internal pointer and check it against NULL. 
  10.  */  
  11. class PtrUtil  
  12. {  
  13. public:  
  14.     static void is_empty(shared_ptr<string> ptr)  
  15.     {  
  16.         ptr != NULL ? cout << "not empty" << endl  
  17.                     : cout << "is empty" << endl;  
  18.     }  
  19. };  
  20.   
  21. /* Method swap() : exchange the content of the shared pointers.  
  22.  *  
  23.  * output:  
  24.  * is empty  
  25.  * not empty  
  26.  * not empty  
  27.  * is empty 
  28.  */  
  29. int main()   
  30. {  
  31.     shared_ptr<string> sp1;  
  32.     shared_ptr<string> sp2(new string("demo"));  
  33.     PtrUtil::is_empty(sp1);  
  34.     PtrUtil::is_empty(sp2);  
  35.   
  36.     sp1.swap(sp2);  
  37.     PtrUtil::is_empty(sp1);  
  38.     PtrUtil::is_empty(sp2);  
  39.   
  40.     return 0;  
  41. }  
#include <iostream>
#include <tr1/memory>
#include <string>

using namespace std;
using std::tr1::shared_ptr;

/* Class shared_ptr defines a bool operator that allows shared pointers to be used in boolean expressions.
 * With auto_ptr, that is not possible; you have to use function get() to access the internal pointer and check it against NULL.
 */
class PtrUtil
{
public:
    static void is_empty(shared_ptr<string> ptr)
    {
        ptr != NULL ? cout << "not empty" << endl
                    : cout << "is empty" << endl;
    }
};

/* Method swap() : exchange the content of the shared pointers. 
 * 
 * output: 
 * is empty 
 * not empty 
 * not empty 
 * is empty
 */
int main() 
{
    shared_ptr<string> sp1;
    shared_ptr<string> sp2(new string("demo"));
    PtrUtil::is_empty(sp1);
    PtrUtil::is_empty(sp2);

    sp1.swap(sp2);
    PtrUtil::is_empty(sp1);
    PtrUtil::is_empty(sp2);

    return 0;
}
7.使用等号赋值
  1. #include <iostream>   
  2. #include <tr1/memory>   
  3.   
  4. using namespace std;  
  5. using std::tr1::shared_ptr;  
  6.   
  7. /* operator= is overloaded so that a shared pointer can be assigned from another shared_ptr or auto_ptr. 
  8.  *  
  9.  * output: 
  10.  * sp1 = 1 
  11.  * sp2 = 2 
  12.  * sp1 = 2 
  13.  */  
  14. int main()  
  15. {   
  16.     shared_ptr<int> sp1(new int(1));   
  17.     cout << "sp1 = " << *sp1 << endl;  
  18.     shared_ptr<int> sp2(new int(2));  
  19.   
  20.     cout << "sp2 = " << *sp2 << endl;  
  21.     sp1 = sp2;  
  22.     cout << "sp1 = " << *sp1 << endl;  
  23.   
  24.     return 0;  
  25. }  
#include <iostream>
#include <tr1/memory>

using namespace std;
using std::tr1::shared_ptr;

/* operator= is overloaded so that a shared pointer can be assigned from another shared_ptr or auto_ptr.
 * 
 * output:
 * sp1 = 1
 * sp2 = 2
 * sp1 = 2
 */
int main()
{ 
    shared_ptr<int> sp1(new int(1)); 
    cout << "sp1 = " << *sp1 << endl;
    shared_ptr<int> sp2(new int(2));

    cout << "sp2 = " << *sp2 << endl;
    sp1 = sp2;
    cout << "sp1 = " << *sp1 << endl;

    return 0;
}
8.unique() 判断当前对象的引用计数==1? ( 比调用use_count()==1要快
  1. #include <iostream>   
  2. #include <tr1/memory>   
  3.   
  4. using namespace std;  
  5. using std::tr1::shared_ptr;  
  6.   
  7. /* Method use_count() returns the number of references to the shared resource (pointed by the current shared pointer object). 
  8.  * Method unique() indicates whether another shared pointed shares the ownership of the same resource or not 
  9.  * (basically, it's identical to 1 == use_count()). 
  10.  *  
  11.  * output:  
  12.  * unique : true  
  13.  * counter : 1  
  14.  * unique : false  
  15.  * counter : 2  
  16.  */   
  17. int main()   
  18. {   
  19.     shared_ptr<std::string> sp1(new string("marius bancila"));   
  20.     cout << "unique : " << std::boolalpha << sp1.unique() << endl;   
  21.     cout << "counter : " << sp1.use_count() << endl;  
  22.   
  23.     shared_ptr<std::string> sp2(sp1);   
  24.     cout << "unique : " << std::boolalpha << sp1.unique() << endl;   
  25.     cout << "counter : " << sp1.use_count() << endl;  
  26.   
  27.     return 0;   
  28. }  
#include <iostream>
#include <tr1/memory>

using namespace std;
using std::tr1::shared_ptr;

/* Method use_count() returns the number of references to the shared resource (pointed by the current shared pointer object).
 * Method unique() indicates whether another shared pointed shares the ownership of the same resource or not
 * (basically, it's identical to 1 == use_count()).
 * 
 * output: 
 * unique : true 
 * counter : 1 
 * unique : false 
 * counter : 2 
 */ 
int main() 
{ 
    shared_ptr<std::string> sp1(new string("marius bancila")); 
    cout << "unique : " << std::boolalpha << sp1.unique() << endl; 
    cout << "counter : " << sp1.use_count() << endl;

    shared_ptr<std::string> sp2(sp1); 
    cout << "unique : " << std::boolalpha << sp1.unique() << endl; 
    cout << "counter : " << sp1.use_count() << endl;

    return 0; 
}
9.reset() 清空当前shared指针,并将所有基于该指针创建的shared指针的引用计数减1, 如果为0, 则删除所指对象。
  1. #include <iostream>   
  2. #include <tr1/memory>    
  3.   
  4. using namespace std;  
  5. using std::tr1::shared_ptr;  
  6.   
  7. class Foo {   
  8. public:   
  9.     void print()  
  10.     {   
  11.          cout << " foo::print" << endl;   
  12.     }   
  13. };  
  14.   
  15. /*Function reset() decrements the shared reference counter. It then transforms the shared pointer to an empty shared_ptr.  
  16.  *  
  17.  * output:  
  18.  * counter sp1: 1  
  19.  * counter sp1: 3  
  20.  * counter sp2: 3  
  21.  * counter sp3: 3  
  22.  * counter sp1: 0  
  23.  * counter sp2: 2  
  24.  * counter sp3: 2  
  25.  * counter sp1: 0  
  26.  * counter sp2: 0  
  27.  * counter sp3: 1  
  28.  */   
  29. int main()   
  30. {  
  31.     // a shared_ptr owns the resouce, counter is 1   
  32.     shared_ptr<Foo> sp1(new Foo);  
  33.     cout << "counter sp1: " << sp1.use_count() << endl;  
  34.     shared_ptr<Foo> sp2(sp1);  
  35.     shared_ptr<Foo> sp3(sp2);  
  36.     cout << "counter sp1: " << sp1.use_count() << endl;  
  37.     cout << "counter sp2: " << sp2.use_count() << endl;  
  38.     cout << "counter sp3: " << sp3.use_count() << endl;  
  39.     // first shared_ptr is reset, the counter decremented and the object becomes empty   
  40.     sp1.reset();  
  41.     cout << "counter sp1: " << sp1.use_count() << endl;  
  42.     cout << "counter sp2: " << sp2.use_count() << endl;  
  43.     cout << "counter sp3: " << sp3.use_count() << endl;  
  44.     sp2.reset();  
  45.     cout << "counter sp1: " << sp1.use_count() << endl;  
  46.     cout << "counter sp2: " << sp2.use_count() << endl;  
  47.     cout << "counter sp3: " << sp3.use_count() << endl;  
  48.   
  49.     return 0;  
  50. }  
#include <iostream>
#include <tr1/memory> 

using namespace std;
using std::tr1::shared_ptr;

class Foo { 
public: 
    void print()
    { 
         cout << " foo::print" << endl; 
    } 
};

/*Function reset() decrements the shared reference counter. It then transforms the shared pointer to an empty shared_ptr. 
 * 
 * output: 
 * counter sp1: 1 
 * counter sp1: 3 
 * counter sp2: 3 
 * counter sp3: 3 
 * counter sp1: 0 
 * counter sp2: 2 
 * counter sp3: 2 
 * counter sp1: 0 
 * counter sp2: 0 
 * counter sp3: 1 
 */ 
int main() 
{
    // a shared_ptr owns the resouce, counter is 1
    shared_ptr<Foo> sp1(new Foo);
    cout << "counter sp1: " << sp1.use_count() << endl;
    shared_ptr<Foo> sp2(sp1);
    shared_ptr<Foo> sp3(sp2);
    cout << "counter sp1: " << sp1.use_count() << endl;
    cout << "counter sp2: " << sp2.use_count() << endl;
    cout << "counter sp3: " << sp3.use_count() << endl;
    // first shared_ptr is reset, the counter decremented and the object becomes empty
    sp1.reset();
    cout << "counter sp1: " << sp1.use_count() << endl;
    cout << "counter sp2: " << sp2.use_count() << endl;
    cout << "counter sp3: " << sp3.use_count() << endl;
    sp2.reset();
    cout << "counter sp1: " << sp1.use_count() << endl;
    cout << "counter sp2: " << sp2.use_count() << endl;
    cout << "counter sp3: " << sp3.use_count() << endl;

    return 0;
}
10.对引用计数的理解,在容器中使用shared_ptr
  1. #include <iostream>    
  2. #include <tr1/memory>    
  3. #include <vector>    
  4. #include <algorithm>   
  5.   
  6. using namespace std;  
  7. using std::tr1::shared_ptr;  
  8.   
  9. /* The following sample shows a vector of shared_ptr to int; a transformation is applied on the elements of the vector,  
  10.  * doubling the value of the pointed objects.  
  11.  *  
  12.  * The program shows the reference counter to show that calling function double_it() does not affect it, even though this function  
  13.  * returns a shared_ptr by value.  
  14.  */   
  15. shared_ptr<int> double_it(const shared_ptr<int>& sp)  
  16. {   
  17.     *sp *= 2;   
  18.     return sp;  
  19. }  
  20.   
  21. /*  
  22.  * output:  
  23.  * initially  
  24.  * 1 (counter = 1)  
  25.  * 2 (counter = 1)  
  26.  * 3 (counter = 1)  
  27.  * after transformation  
  28.  * 2 (counter = 1)  
  29.  * 4 (counter = 1)  
  30.  * 6 (counter = 1)  
  31.  */  
  32. int main()  
  33. {  
  34.     vector<shared_ptr<int> > numbers;  
  35.     numbers.push_back(shared_ptr<int>(new int(1)));   
  36.     numbers.push_back(shared_ptr<int>(new int(2)));   
  37.     numbers.push_back(shared_ptr<int>(new int(3)));   
  38.   
  39.     cout << "initially" << endl;   
  40.     for (vector<shared_ptr<int> >::const_iterator it = numbers.begin(); it != numbers.end(); ++it)  
  41.         cout << **it << " (counter = " << (*it).use_count() << ")" << endl;   
  42.     std::transform(numbers.begin(), numbers.end(), numbers.begin(), double_it);   
  43.   
  44.     cout << "after transformation" << endl;   
  45.     for (vector<shared_ptr<int> >::const_iterator it = numbers.begin(); it != numbers.end(); ++it)   
  46.         cout << **it << " (counter = " << (*it).use_count() << ")" << endl;  
  47.   
  48.     return 0;   
  49. }  
#include <iostream> 
#include <tr1/memory> 
#include <vector> 
#include <algorithm>

using namespace std;
using std::tr1::shared_ptr;

/* The following sample shows a vector of shared_ptr to int; a transformation is applied on the elements of the vector, 
 * doubling the value of the pointed objects. 
 * 
 * The program shows the reference counter to show that calling function double_it() does not affect it, even though this function 
 * returns a shared_ptr by value. 
 */ 
shared_ptr<int> double_it(const shared_ptr<int>& sp)
{ 
    *sp *= 2; 
    return sp;
}

/* 
 * output: 
 * initially 
 * 1 (counter = 1) 
 * 2 (counter = 1) 
 * 3 (counter = 1) 
 * after transformation 
 * 2 (counter = 1) 
 * 4 (counter = 1) 
 * 6 (counter = 1) 
 */
int main()
{
    vector<shared_ptr<int> > numbers;
    numbers.push_back(shared_ptr<int>(new int(1))); 
    numbers.push_back(shared_ptr<int>(new int(2))); 
    numbers.push_back(shared_ptr<int>(new int(3))); 

    cout << "initially" << endl; 
    for (vector<shared_ptr<int> >::const_iterator it = numbers.begin(); it != numbers.end(); ++it)
        cout << **it << " (counter = " << (*it).use_count() << ")" << endl; 
    std::transform(numbers.begin(), numbers.end(), numbers.begin(), double_it); 

    cout << "after transformation" << endl; 
    for (vector<shared_ptr<int> >::const_iterator it = numbers.begin(); it != numbers.end(); ++it) 
        cout << **it << " (counter = " << (*it).use_count() << ")" << endl;

    return 0; 
}
11.多态情况下的shared指针使用(声明基类句柄,创建子类对象)
  1. #include <iostream>    
  2. #include <tr1/memory>    
  3. #include <vector>   
  4. #include <string>   
  5.   
  6. using namespace std;  
  7. using std::tr1::shared_ptr;  
  8.   
  9. /*shared_ptr can work with class hierarchies, so that shared<D> is convertible to shared<B>, where D is a class (or struct) derived  
  10.  * from B. The following class hierarchy is used to demonstrate the concept.  
  11.  */   
  12. class Item   
  13. {   
  14.     string title_;   
  15. public:   
  16.     Item(const string& title) : title_(title){}   
  17.     virtual ~Item(){}  
  18.     virtual string Description() const = 0;   
  19.     string Title() const  
  20.     {   
  21.         return title_;  
  22.     }   
  23. };  
  24.   
  25. class Book: public Item  
  26. {   
  27.     int pages_;  
  28. public:   
  29.     Book(const string& title, int pages):Item(title), pages_(pages){}  
  30.     virtual string Description() const  
  31.     {   
  32.         return "Book: " + Title();   
  33.     }  
  34.     int Pages() const  
  35.     {  
  36.         return pages_;  
  37.     }  
  38. };  
  39.   
  40. class DVD: public Item   
  41. {   
  42.     int tracks_;   
  43. public:   
  44.     DVD(const string& title, int tracks):Item(title), tracks_(tracks){}  
  45.     virtual string Description() const  
  46.     {  
  47.         return "DVD: " + Title();  
  48.     }  
  49.     int Tracks() const  
  50.     {  
  51.         return tracks_;  
  52.     }  
  53. };  
  54.   
  55. /*  
  56.  * output:  
  57.  * Book: Effective STL  
  58.  * DVD: Left of the Middle  
  59.  */   
  60. int main()  
  61. {  
  62.     vector<shared_ptr<Item> > items;  
  63.     items.push_back(shared_ptr<Book>(new Book("Effective STL", 400)));  
  64.     items.push_back(shared_ptr<DVD>(new DVD("Left of the Middle", 14)));  
  65.   
  66.     for (vector<shared_ptr<Item> >::const_iterator it = items.begin(); it != items.end(); ++it)  
  67.         cout << (*it)->Description() << endl;  
  68.   
  69.     return 0;  
  70. }  
#include <iostream> 
#include <tr1/memory> 
#include <vector>
#include <string>

using namespace std;
using std::tr1::shared_ptr;

/*shared_ptr can work with class hierarchies, so that shared<D> is convertible to shared<B>, where D is a class (or struct) derived 
 * from B. The following class hierarchy is used to demonstrate the concept. 
 */ 
class Item 
{ 
    string title_; 
public: 
    Item(const string& title) : title_(title){} 
    virtual ~Item(){}
    virtual string Description() const = 0; 
    string Title() const
    { 
        return title_;
    } 
};

class Book: public Item
{ 
    int pages_;
public: 
    Book(const string& title, int pages):Item(title), pages_(pages){}
    virtual string Description() const
    { 
        return "Book: " + Title(); 
    }
    int Pages() const
    {
        return pages_;
    }
};

class DVD: public Item 
{ 
    int tracks_; 
public: 
    DVD(const string& title, int tracks):Item(title), tracks_(tracks){}
    virtual string Description() const
    {
        return "DVD: " + Title();
    }
    int Tracks() const
    {
        return tracks_;
    }
};

/* 
 * output: 
 * Book: Effective STL 
 * DVD: Left of the Middle 
 */ 
int main()
{
    vector<shared_ptr<Item> > items;
    items.push_back(shared_ptr<Book>(new Book("Effective STL", 400)));
    items.push_back(shared_ptr<DVD>(new DVD("Left of the Middle", 14)));

    for (vector<shared_ptr<Item> >::const_iterator it = items.begin(); it != items.end(); ++it)
        cout << (*it)->Description() << endl;

    return 0;
}
12.dynamic_cast,使用dynamic_pointer_cast将基类向下转型为子类
  1. #include <iostream>   
  2. #include <tr1/memory>   
  3. #include <string>   
  4.   
  5. using namespace std;  
  6. using std::tr1::shared_ptr;  
  7.   
  8. /*shared_ptr can work with class hierarchies, so that shared<D> is convertible to shared<B>, where D is a class (or struct) derived   
  9.  * from B. The following class hierarchy is used to demonstrate the concept.   
  10.  */  
  11. class Item  
  12. {  
  13.     string title_;  
  14. public:  
  15.     Item(const string& title) : title_(title){}  
  16.     virtual ~Item(){}  
  17.     virtual string Description() const = 0;  
  18.     string Title() const  
  19.     {  
  20.         returntitle_;  
  21.     }  
  22. };  
  23.   
  24. class Book: public Item  
  25. {    
  26.     int pages_;  
  27. public:    
  28.     Book(const string& title, int pages):Item(title), pages_(pages){}  
  29.     virtual string Description() const   
  30.     {    
  31.         return "Book: " + Title();        
  32.     }  
  33.     int Pages() const        
  34.     {    
  35.         return pages_;    
  36.     }    
  37. };  
  38.       
  39. class DVD: public Item    
  40. {    
  41.     int tracks_;    
  42. public:    
  43.     DVD(const string& title, int tracks):Item(title), tracks_(tracks){}      
  44.     virtual string Description() const        
  45.     {    
  46.         return "DVD: " + Title();    
  47.     }    
  48.     int Tracks() const        
  49.     {    
  50.         return tracks_;    
  51.     }    
  52. };      
  53.   
  54. /* To convert back, from shared_ptr<B> to shared_ptr<D>, where D is a class (or structure) derived from B,   
  55.  * you can use the cast function std::tr1::dynamic_pointer_cast.   
  56.  *   
  57.  * output:   
  58.  * spi counter: 1   
  59.  * Left of the Middle, 14 tracks   
  60.  * spi counter: 2 
  61.  * spb counter: 0 
  62.  * spd counter: 2 
  63.  */    
  64. int main()  
  65. {  
  66.     shared_ptr<Item> spi(new DVD("Left of the Middle", 14));  
  67.     cout << "spi counter: " << spi.use_count() << endl;  
  68.     shared_ptr<Book> spb = std::tr1::dynamic_pointer_cast<Book>(spi);  
  69.     if (spb != NULL)  
  70.         cout << spb->Title() << ", " << spb->Pages() << " pages" << endl;  
  71.     shared_ptr<DVD> spd = std::tr1::dynamic_pointer_cast<DVD>(spi);  
  72.     if (spd != NULL)    
  73.         cout << spd->Title() << ", " << spd->Tracks() << " tracks" << endl;  
  74.     cout << "spi counter: " << spi.use_count() << endl;  
  75.     cout << "spb counter: " << spb.use_count() << endl;  
  76.     cout << "spd counter: " << spd.use_count() << endl;  
  77.   
  78.     return 0;  
  79. }  
#include <iostream>
#include <tr1/memory>
#include <string>

using namespace std;
using std::tr1::shared_ptr;

/*shared_ptr can work with class hierarchies, so that shared<D> is convertible to shared<B>, where D is a class (or struct) derived  
 * from B. The following class hierarchy is used to demonstrate the concept.  
 */
class Item
{
    string title_;
public:
    Item(const string& title) : title_(title){}
    virtual ~Item(){}
    virtual string Description() const = 0;
    string Title() const
    {
        returntitle_;
    }
};

class Book: public Item
{  
    int pages_;
public:  
    Book(const string& title, int pages):Item(title), pages_(pages){}
    virtual string Description() const 
    {  
        return "Book: " + Title();      
    }
    int Pages() const      
    {  
        return pages_;  
    }  
};
    
class DVD: public Item  
{  
    int tracks_;  
public:  
    DVD(const string& title, int tracks):Item(title), tracks_(tracks){}    
    virtual string Description() const      
    {  
        return "DVD: " + Title();  
    }  
    int Tracks() const      
    {  
        return tracks_;  
    }  
};    

/* To convert back, from shared_ptr<B> to shared_ptr<D>, where D is a class (or structure) derived from B,  
 * you can use the cast function std::tr1::dynamic_pointer_cast.  
 *  
 * output:  
 * spi counter: 1  
 * Left of the Middle, 14 tracks  
 * spi counter: 2
 * spb counter: 0
 * spd counter: 2
 */  
int main()
{
    shared_ptr<Item> spi(new DVD("Left of the Middle", 14));
    cout << "spi counter: " << spi.use_count() << endl;
    shared_ptr<Book> spb = std::tr1::dynamic_pointer_cast<Book>(spi);
    if (spb != NULL)
        cout << spb->Title() << ", " << spb->Pages() << " pages" << endl;
    shared_ptr<DVD> spd = std::tr1::dynamic_pointer_cast<DVD>(spi);
    if (spd != NULL)  
        cout << spd->Title() << ", " << spd->Tracks() << " tracks" << endl;
    cout << "spi counter: " << spi.use_count() << endl;
    cout << "spb counter: " << spb.use_count() << endl;
    cout << "spd counter: " << spd.use_count() << endl;

    return 0;
}
13.static cast,使用static_pointer_cast将void转型为char,观察引用计数的变化
  1. #include <iostream>   
  2. #include <tr1/memory>    
  3. #include <vector>   
  4.   
  5. using namespace std;  
  6. using std::tr1::shared_ptr;  
  7.   
  8. /* A second cast function is std::tr1::static_pointer_cast. It returns an empty shared_ptr if the original object is empty, 
  9.  * or a shared_ptr<T> object that owns the resource that is owned by the original object. The expression static_cast<T*>(r.get()) 
  10.  * must be valid. 
  11.  * 
  12.  * In the next sample, a vector holds shared_ptr to void. The first element is statically cast to shared_ptr<char>. 
  13.  * The cast is valid as long as the source is not empty, regardless of whether the types are compatible or not. 
  14.  * 
  15.  * output:  
  16.  * after creating the shared pointer  
  17.  * -1   sp1 counter: 1 
  18.  * after adding to the vector  
  19.  * -2   sp1 counter: 2  
  20.  * A  
  21.  * after casting  
  22.  * -3   sp1 counter: 3  
  23.  * -4   spc counter: 3  
  24.  */   
  25. int main()   
  26. {  
  27.     vector<shared_ptr<void> > items;  
  28.     shared_ptr<char> sp1(new char('A'));  
  29.     shared_ptr<short> sp2(new short(66));  
  30.     cout << "after creating the shared pointer" << endl;  
  31.     cout << "-1    sp1 counter: " << sp1.use_count() << endl;  
  32.     items.push_back(sp1);  
  33.     items.push_back(sp2);  
  34.     cout << "after adding to the vector" << endl;  
  35.     cout << "-2    sp1 counter: " << sp1.use_count() << endl;  
  36.     shared_ptr<char> spc = tr1::static_pointer_cast<char>(*(items.begin()));  
  37.     if (spc != NULL)   
  38.         cout << *spc << endl;   
  39.     cout << "after casting" << endl;   
  40.     cout << "-3    sp1 counter: " << sp1.use_count() << endl;   
  41.     cout << "-4    spc counter: " << spc.use_count() << endl;  
  42.   
  43.     return 0;  
  44. }  
#include <iostream>
#include <tr1/memory> 
#include <vector>

using namespace std;
using std::tr1::shared_ptr;

/* A second cast function is std::tr1::static_pointer_cast. It returns an empty shared_ptr if the original object is empty,
 * or a shared_ptr<T> object that owns the resource that is owned by the original object. The expression static_cast<T*>(r.get())
 * must be valid.
 *
 * In the next sample, a vector holds shared_ptr to void. The first element is statically cast to shared_ptr<char>.
 * The cast is valid as long as the source is not empty, regardless of whether the types are compatible or not.
 *
 * output: 
 * after creating the shared pointer 
 * -1   sp1 counter: 1
 * after adding to the vector 
 * -2   sp1 counter: 2 
 * A 
 * after casting 
 * -3   sp1 counter: 3 
 * -4   spc counter: 3 
 */ 
int main() 
{
    vector<shared_ptr<void> > items;
    shared_ptr<char> sp1(new char('A'));
    shared_ptr<short> sp2(new short(66));
    cout << "after creating the shared pointer" << endl;
    cout << "-1    sp1 counter: " << sp1.use_count() << endl;
    items.push_back(sp1);
    items.push_back(sp2);
    cout << "after adding to the vector" << endl;
    cout << "-2    sp1 counter: " << sp1.use_count() << endl;
    shared_ptr<char> spc = tr1::static_pointer_cast<char>(*(items.begin()));
    if (spc != NULL) 
        cout << *spc << endl; 
    cout << "after casting" << endl; 
    cout << "-3    sp1 counter: " << sp1.use_count() << endl; 
    cout << "-4    spc counter: " << spc.use_count() << endl;

    return 0;
}
14.const cast,如果声明std::tr1::shared_ptr<const int> csp,可以声明
std::tr1::shared_ptr<int> sp = std::tr1::const_pointer_cast<int>(csp);
  1. #include <iostream>   
  2. #include <tr1/memory>   
  3.   
  4. using namespace std;  
  5. using std::tr1::shared_ptr;  
  6.   
  7. /* To modify the value of the pointer object the const specifier must be removed. This is shown below.  
  8.  * 
  9.  * output: 
  10.  * csp counter: 1 
  11.  * 15 
  12.  * 15 
  13.  * csp counter: 2 
  14.  * sp counter: 2 
  15.  */   
  16. int main()  
  17. {  
  18.     shared_ptr<const int> csp(new int(5));  
  19.     cout << "csp counter: " << csp.use_count() << endl;  
  20.     shared_ptr<int> sp = std::tr1::const_pointer_cast<int>(csp);   
  21.     *sp += 10;  
  22.     cout << *csp << endl;  
  23.     cout << *sp << endl;  
  24.     cout << "csp counter: " << csp.use_count() << endl;  
  25.     cout << "sp counter: " << sp.use_count() << endl;  
  26.   
  27.     return 0;   
  28. }  
#include <iostream>
#include <tr1/memory>

using namespace std;
using std::tr1::shared_ptr;

/* To modify the value of the pointer object the const specifier must be removed. This is shown below. 
 *
 * output:
 * csp counter: 1
 * 15
 * 15
 * csp counter: 2
 * sp counter: 2
 */ 
int main()
{
    shared_ptr<const int> csp(new int(5));
    cout << "csp counter: " << csp.use_count() << endl;
    shared_ptr<int> sp = std::tr1::const_pointer_cast<int>(csp); 
    *sp += 10;
    cout << *csp << endl;
    cout << *sp << endl;
    cout << "csp counter: " << csp.use_count() << endl;
    cout << "sp counter: " << sp.use_count() << endl;

    return 0; 
}
15.weak_ptr的lock() 类似于shared_ptr的get()
  1. #include <iostream>    
  2. #include <tr1/memory>   
  3.   
  4. using namespace std;  
  5. using std::tr1::shared_ptr;  
  6. using std::tr1::weak_ptr;  
  7.   
  8. /* The major weakness of shared_ptr is that it cannot detect cyclic dependencies. In this case, the reference counter is incremented  
  9.  * more than it should actually be, so that the resources are no longer released when the shared pointer objects go out of scope.  
  10.  * To fix this problem, a second smart pointer was created, weak_ptr, that points to a resource owned by a shared_ptr but does not 
  11.  * affect the reference counter; it is a "weak reference." When the last shared_ptr that owns the resource referred by a weak_ptr, 
  12.  * the resource is released and the weak pointer is marked as invalid. To check whether a weak_ptr is valid or not, you can use 
  13.  * function expired() that returns true if the pointer was marked as invalid. 
  14.  */  
  15. /* Even though function get() (that provides direct access to the wrapped pointer) is available, it's not recommended to use it even 
  16.  * in single-threaded applications. The safe alternative is function lock() that returns a shread_ptr sharing the resource pointed by 
  17.  * the weak pointer. 
  18.  */  
  19. void show(const weak_ptr<int>& wp)  
  20. {  
  21.     shared_ptr<int> sp = wp.lock();  
  22.     cout << *sp << endl;   
  23. }  
  24.   
  25. /* 
  26.  * output: 
  27.  * 44 
  28.  * expired : true 
  29.  */  
  30. int main()  
  31. {  
  32.     weak_ptr<int> wp;  
  33.     {  
  34.         shared_ptr<int> sp(new int(44));  
  35.         wp = sp;  
  36.         show(wp);  
  37.     }  
  38.     cout << "expired : " << boolalpha << wp.expired() << endl;  
  39.       
  40.     return 0;  
  41. }  
#include <iostream> 
#include <tr1/memory>

using namespace std;
using std::tr1::shared_ptr;
using std::tr1::weak_ptr;

/* The major weakness of shared_ptr is that it cannot detect cyclic dependencies. In this case, the reference counter is incremented 
 * more than it should actually be, so that the resources are no longer released when the shared pointer objects go out of scope. 
 * To fix this problem, a second smart pointer was created, weak_ptr, that points to a resource owned by a shared_ptr but does not
 * affect the reference counter; it is a "weak reference." When the last shared_ptr that owns the resource referred by a weak_ptr,
 * the resource is released and the weak pointer is marked as invalid. To check whether a weak_ptr is valid or not, you can use
 * function expired() that returns true if the pointer was marked as invalid.
 */
/* Even though function get() (that provides direct access to the wrapped pointer) is available, it's not recommended to use it even
 * in single-threaded applications. The safe alternative is function lock() that returns a shread_ptr sharing the resource pointed by
 * the weak pointer.
 */
void show(const weak_ptr<int>& wp)
{
    shared_ptr<int> sp = wp.lock();
    cout << *sp << endl; 
}

/*
 * output:
 * 44
 * expired : true
 */
int main()
{
    weak_ptr<int> wp;
    {
        shared_ptr<int> sp(new int(44));
        wp = sp;
        show(wp);
    }
    cout << "expired : " << boolalpha << wp.expired() << endl;
    
    return 0;
}
16.一个使用shared_ptr和weak_ptr的二叉树数据结构示例
  1. #include <iostream>    
  2. #include <tr1/memory>    
  3. #include <vector>   
  4. #include <string>   
  5.   
  6. using namespace std;  
  7. using std::tr1::shared_ptr;  
  8. using std::tr1::weak_ptr;  
  9.   
  10. /* The following sample shows such a tree, but uses a weak_ptr to solve the cyclic dependency.*/   
  11. class Node  
  12. {  
  13.     string value_;  
  14.     shared_ptr<Node> left_;  
  15.     shared_ptr<Node> right_;  
  16.     weak_ptr<Node> parent_;  
  17. public:  
  18.     Node(const string value):value_(value){}  
  19.   
  20.     string Value() const { return value_; }  
  21.     shared_ptr<Node> Left() const { return left_; }   
  22.     shared_ptr<Node> Right() const { return right_; }  
  23.     weak_ptr<Node> Parent() const { return parent_; }  
  24.     void SetParent(shared_ptr<Node> node)  
  25.     {  
  26.         parent_.reset();  
  27.         parent_ = node;  
  28.     }  
  29.     void SetLeft(shared_ptr<Node> node)  
  30.     {  
  31.         left_.reset();  
  32.         left_ = node;  
  33.     }  
  34.     void SetRight(shared_ptr<Node> node)  
  35.     {  
  36.         right_.reset();  
  37.         right_ = node;  
  38.     }  
  39. };  
  40.   
  41. string path(const shared_ptr<Node>& item)  
  42. {  
  43.     weak_ptr<Node> wparent = item->Parent();  
  44.     shared_ptr<Node> sparent = wparent.lock();  
  45.     if (sparent)  
  46.     {  
  47.         return path(sparent) + "\\" + item->Value();   
  48.     }  
  49.     return item->Value();  
  50. }  
  51.   
  52. /* 
  53.  * output: 
  54.  * C:\dir1\dir11 
  55. */  
  56. int main()  
  57. {  
  58.     shared_ptr<Node> root(new Node("C:"));  
  59.     shared_ptr<Node> child1(new Node("dir1"));  
  60.     shared_ptr<Node> child2(new Node("dir2"));  
  61.     root->SetLeft(child1);  
  62.     child1->SetParent(root);  
  63.     root->SetRight(child2);  
  64.     child2->SetParent(root);  
  65.     shared_ptr<Node> child11(new Node("dir11"));  
  66.     child1->SetLeft(child11);  
  67.     child11->SetParent(child1);  
  68.     cout << "path: " << path(child11) << endl;  
  69.   
  70.     return 0;  
  71. }  
  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值