您的位置:首页 > 编程语言 > C语言/C++

C++:智能指针-TR1的shared_ptr和weak_ptr使用介绍

2014-02-13 23:08 996 查看
shared_ptr: Based on a reference counter model, with the counter incremented each time a new shared pointer object points to the resource, and decremented when the object's destructor executes; when the counter gets to 0, the resource is released. This pointer
is copy constructable and assignable; this makes it usable in STL containers. Moreover, the shared pointer works with polymorphic types and incomplete types. Its major drawback is the impossibility to detect cyclic dependencies, in which case the resources
never get released (for example, a tree with nodes having (shared) pointers to children but also to the parent, in which case the parent and the children are referencing each other, in a cycle). To fix this issue, a second smart pointer was created:

weak_ptr: Points to a resource referred by a shared pointer, but does not participate in reference counting. When the counters gets to 0, the resource is released, regardless the number of weak pointers referring it; all these pointers are marked as invalid.

A sharted_ptr object has the ownership of an object if:

 * It was constructed with a pointer to that resource;

 * It was constructed from a shared_ptr object that owns that resource;

 * It was constructed from a weak_ptr object that points to that resource;

Ownership of that resource was assigned to it, either with shared_ptr::operator= or by calling the member function shared_ptr::reset().

Can create a new shared_ptr from:

 * A pointer to any type T (including const T), having the possibility of specifying a deleter for the pointed resource;

 * Another shared_ptr object;

 * A weak_ptr object;

 * An auto_ptr object;

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

   1. #include <iostream>

   2. #include <tr1/memory>

   3. 

   4. class Foo

   5. {

   6. public:

   7.     void print()

   8.     {

   9.         std::cout << " foo::print" << std::endl;

  10.     }

  11. };

  12. 

  13. /* When sp2 is created, sp1 increments the reference counter.

  14.  * When the two shared pointer objects get out of scope, the last

  15.  * one that is destroyed will release the resource.

  16.  *

  17.  * output:

  18.  * foo::print

  19.  * sp1 pointer: 0x90a7008

  20.  * foo::print

  21.  * sp1 pointer: 0x90a7008

  22.  * sp2 pointer: 0x90a7008

  23.  * counter sp1: 2

  24.  * counter sp2: 2

  25.  */

  26. int main()

  27. {

  28.     std::tr1::shared_ptr<Foo> sp1(new Foo);

  29.     sp1->print();

  30.     std::cout << "sp1 pointer: " << sp1.get() << std::endl;

  31. 

  32.     std::tr1::shared_ptr<Foo> sp2(sp1);

  33.     sp2->print();

  34.     std::cout << "sp1 pointer: " << sp1.get() << std::endl;

  35.     std::cout << "sp2 pointer: " << sp2.get() << std::endl;

  36. 

  37.     std::cout << "counter sp1: " << sp1.use_count() << std::endl;

  38.     std::cout << "counter sp2: " << sp2.use_count() << std::endl;

  39. 

  40.     return 0;

  41. }

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

   1. #include <iostream>

   2. #include <tr1/memory>

   3. 

   4. class Foo

   5. {

   6. public:

   7.     void print()

   8.     {

   9.         std::cout << " foo::print" << std::endl;

  10.     }

  11. };

  12. 

  13. /* The next sample shows a shared_ptr created from an auto_ptr object. The auto pointer gives up the ownership of the resource,

  14.  * resetting its wrapped pointer to NULL.

  15.  *

  16.  * output:

  17.  * foo::print

  18.  * ap1 pointer: 0x99b8008

  19.  * foo::print

  20.  * ap1 pointer: 0

  21.  * sp1 pointer: 0x99b8008

  22.  */

  23. int main()

  24. {

  25.     std::auto_ptr<Foo> ap1(new Foo);

  26.     ap1->print();

  27.     std::cout << "ap1 pointer: " << ap1.get() << std::endl;

  28. 

  29.     std::tr1::shared_ptr<Foo> sp1(ap1);

  30.     sp1->print();

  31.     std::cout << "ap1 pointer: " << ap1.get() << std::endl;

  32.     std::cout << "sp1 pointer: " << sp1.get() << std::endl;

  33. 

  34.     return 0;

  35. }

3.在shared_ptr构造函数中,行参指定构造对象和析构对象的函数

   1. #include <iostream>

   2. #include <tr1/memory>

   3. 

   4. class Foo

   5. {

   6. public:

   7.     void print()

   8.     {

   9.         std::cout << " foo::print" << std::endl;

  10.     }

  11. };

  12. 

  13. class FooHandler

  14. {

  15. public:

  16.     static Foo* alloc()

  17.     {

  18.         Foo* f = new Foo;

  19.         std::cout << " a new foo was created" << std::endl;

  20.         return f;

  21.     }

  22. 

  23.     static void free(Foo* f)

  24.     {

  25.         delete f;

  26.         std::cout << " foo destroyed" << std::endl;

  27.     }

  28. };

  29. 

  30. /*

  31.  * Each time a new object is created or destroyed, a message is printed in the output window (for simplicity, you will ignore the copy

  32.  * construction or assignment). Function FooHandler::free can be provided as a delete to the shared_ptr constructor. As a result,

  33.  * when the resource is deleted a message is printed in the output window (you have to run in debugger to see it).

  34.  *

  35.  * output:

  36.  * a new foo was created

  37.  * foo::print

  38.  * foo destroyed

  39.  */

  40. int main()

  41. {

  42.     std::tr1::shared_ptr<Foo> ptr(FooHandler::alloc(), &FooHandler::free);

  43.     ptr->print();

  44. 

  45.     return 0;

  46. }

4.get() 返回对象指针,使用->调用成员函数

   1. #include <iostream>

   2. #include <tr1/memory>

   3. 

   4. class Foo

   5. {

   6. public:

   7.     void print()

   8.     {

   9.         std::cout << " foo::print" << std::endl;

  10.     }

  11. };

  12. 

  13. /*

  14.  * Function get() returns the wrapped pointer to the resource (basically identical to operator-> and available for compatibility

  15.  * with auto_ptr).

  16.  *

  17.  * output:

  18.  * foo::print

  19.  */

  20. int main()

  21. {

  22.     std::tr1::shared_ptr<Foo> sp(new Foo);

  23.     Foo* f = sp.get();

  24.     if (f)

  25.         f->print();

  26. 

  27.     return 0;

  28. }

5.get() 返回对象指针,if判断是否为null

   1. #include <iostream>

   2. #include <tr1/memory>

   3. 

   4. /* Class shared_ptr defines a bool operator that allows shared pointers to be used in boolean expressions.

   5.  * With auto_ptr, that is not possible; you have to use function get() to access the internal pointer and check it against NULL.

   6.  */

   7. class PtrUtil

   8. {

   9. public:

  10.     static void is_empty(std::tr1::shared_ptr<std::string> ptr)

  11.     {

  12.         if (ptr)

  13.             std::cout << "not empty" << std::endl;

  14.         else

  15.             std::cout << "is empty" << std::endl;

  16.     }

  17. };

  18. 

  19. /*

  20.  * output:

  21.  * is empty

  22.  * not empty

  23.  */

  24. int main()

  25. {

  26.     std::tr1::shared_ptr<std::string> sp1;

  27.     std::tr1::shared_ptr<std::string> sp2(new std::string("demo"));

  28. 

  29.     PtrUtil::is_empty(sp1);

  30.     PtrUtil::is_empty(sp2);

  31. 

  32.     return 0;

  33. }

6.swap() 交换两个shared_ptr所指向的对象

   1. #include <iostream>

   2. #include <tr1/memory>

   3. 

   4. class PtrUtil

   5. {

   6. public:

   7.     static void is_empty(std::tr1::shared_ptr<std::string> ptr)

   8.     {

   9.         if (ptr)

  10.             std::cout << "not empty" << std::endl;

  11.         else

  12.             std::cout << "is empty" << std::endl;

  13.     }

  14. };

  15. 

  16. /* Method swap() : exchange the content of the shared pointers.

  17.  *

  18.  * output:

  19.  * is empty

  20.  * not empty

  21.  * not empty

  22.  * is empty

  23.  */

  24. int main()

  25. {

  26.     std::tr1::shared_ptr<std::string> sp1;

  27.     std::tr1::shared_ptr<std::string> sp2(new std::string("demo"));

  28. 

  29.     PtrUtil::is_empty(sp1);

  30.     PtrUtil::is_empty(sp2);

  31. 

  32.     sp1.swap(sp2);

  33. 

  34.     PtrUtil::is_empty(sp1);

  35.     PtrUtil::is_empty(sp2);

  36. 

  37.     return 0;

  38. }

7.使用等号赋值

   1. #include <iostream>

   2. #include <tr1/memory>

   3. 

   4. /* operator= is overloaded so that a shared pointer can be assigned from another shared_ptr or auto_ptr.

   5.  *

   6.  * output:

   7.  * sp1 = 1

   8.  * sp2 = 2

   9.  * sp1 = 2

  10.  */

  11. int main()

  12. {

  13.     std::tr1::shared_ptr<int> sp1(new int(1));

  14.     std::cout << "sp1 = " << *sp1 << std::endl;

  15. 

  16.     std::tr1::shared_ptr<int> sp2(new int(2));

  17.     std::cout << "sp2 = " << *sp2 << std::endl;

  18. 

  19.     sp1 = sp2;

  20.     std::cout << "sp1 = " << *sp1 << std::endl;

  21. 

  22.     return 0;

  23. }

8.unique() 判断当前对象的引用计数==1?

   1. #include <iostream>

   2. #include <tr1/memory>

   3. 

   4. /* Method use_count() returns the number of references to the shared resource (pointed by the current shared pointer object).

   5.  * Method unique() indicates whether another shared pointed shares the ownership of the same resource or not

   6.  * (basically, it's identical to 1 == use_count()).

   7.  *

   8.  * output:

   9.  * unique : true

  10.  * counter : 1

  11.  * unique : false

  12.  * counter : 2

  13.  */

  14. int main()

  15. {

  16.     std::tr1::shared_ptr<std::string> sp1(new std::string("marius bancila"));

  17.     std::cout << "unique : " << std::boolalpha << sp1.unique() << std::endl;

  18.     std::cout << "counter : " << sp1.use_count() << std::endl;

  19.     std::tr1::shared_ptr<std::string> sp2(sp1);

  20.     std::cout << "unique : " << std::boolalpha << sp1.unique() << std::endl;

  21.     std::cout << "counter : " << sp1.use_count() << std::endl;

  22. 

  23.     return 0;

  24. }

9.reset() 清空当前shared指针,并将所有基于该指针创建的shared指针的引用计数减1

   1. #include <iostream>

   2. #include <tr1/memory>

   3. 

   4. class Foo

   5. {

   6. public:

   7.     void print()

   8.     {

   9.         std::cout << " foo::print" << std::endl;

  10.     }

  11. };

  12. 

  13. /*Function reset() decrements the shared reference counter. It then transforms the shared pointer to an empty shared_ptr.

  14.  *

  15.  * output:

  16.  * counter sp1: 1

  17.  * counter sp1: 3

  18.  * counter sp2: 3

  19.  * counter sp3: 3

  20.  * counter sp1: 0

  21.  * counter sp2: 2

  22.  * counter sp3: 2

  23.  * counter sp1: 0

  24.  * counter sp2: 0

  25.  * counter sp3: 1

  26.  */

  27. int main()

  28. {

  29.     // a shared_ptr owns the resouce, counter is 1

  30.     std::tr1::shared_ptr<Foo> sp1(new Foo);

  31.     std::cout << "counter sp1: " << sp1.use_count() << std::endl;

  32. 

  33.     std::tr1::shared_ptr<Foo> sp2(sp1);

  34.     std::tr1::shared_ptr<Foo> sp3(sp2);

  35.     std::cout << "counter sp1: " << sp1.use_count() << std::endl;

  36.     std::cout << "counter sp2: " << sp2.use_count() << std::endl;

  37.     std::cout << "counter sp3: " << sp3.use_count() << std::endl;

  38. 

  39.     // first shared_ptr is reset, the counter decremented and the object becomes empty

  40.     sp1.reset();

  41.     std::cout << "counter sp1: " << sp1.use_count() << std::endl;

  42.     std::cout << "counter sp2: " << sp2.use_count() << std::endl;

  43.     std::cout << "counter sp3: " << sp3.use_count() << std::endl;

  44. 

  45.     sp2.reset();

  46.     std::cout << "counter sp1: " << sp1.use_count() << std::endl;

  47.     std::cout << "counter sp2: " << sp2.use_count() << std::endl;

  48.     std::cout << "counter sp3: " << sp3.use_count() << std::endl;

  49. 

  50.     return 0;

  51. }

10.对引用计数的理解,在容器中使用shared_ptr

   1. #include <iostream>

   2. #include <tr1/memory>

   3. #include <vector>

   4. #include <algorithm>

   5. 

   6. /* The following sample shows a vector of shared_ptr to int; a transformation is applied on the elements of the vector,

   7.  * doubling the value of the pointed objects.

   8.  *

   9.  * The program shows the reference counter to show that calling function double_it() does not affect it, even though this function

  10.  * returns a shared_ptr by value.

  11.  */

  12. std::tr1::shared_ptr<int> double_it(const std::tr1::shared_ptr<int>& sp)

  13. {

  14.     *sp *= 2;

  15.     return sp;

  16. }

  17. 

  18. /*

  19.  * output:

  20.  * initially

  21.  * 1 (counter = 1)

  22.  * 2 (counter = 1)

  23.  * 3 (counter = 1)

  24.  * after transformation

  25.  * 2 (counter = 1)

  26.  * 4 (counter = 1)

  27.  * 6 (counter = 1)

  28.  */

  29. int main()

  30. {

  31.     std::vector<std::tr1::shared_ptr<int> > numbers;

  32. 

  33.     numbers.push_back(std::tr1::shared_ptr<int>(new int(1)));

  34.     numbers.push_back(std::tr1::shared_ptr<int>(new int(2)));

  35.     numbers.push_back(std::tr1::shared_ptr<int>(new int(3)));

  36. 

  37.     std::cout << "initially" << std::endl;

  38.     for (std::vector<std::tr1::shared_ptr<int> >::const_iterator it =

  39.             numbers.begin(); it != numbers.end(); ++it)

  40.         std::cout << **it << " (counter = " << (*it).use_count() << ")"

  41.                 << std::endl;

  42.     std::transform(numbers.begin(), numbers.end(), numbers.begin(), double_it);

  43.     std::cout << "after transformation" << std::endl;

  44.     for (std::vector<std::tr1::shared_ptr<int> >::const_iterator it =

  45.             numbers.begin(); it != numbers.end(); ++it)

  46.         std::cout << **it << " (counter = " << (*it).use_count() << ")"

  47.                 << std::endl;

  48. 

  49.     return 0;

  50. }

11.多态情况下的shared指针使用(声明基类句柄,创建子类对象)

   1. #include <iostream>

   2. #include <tr1/memory>

   3. #include <vector>

   4. 

   5. /*shared_ptr can work with class hierarchies, so that shared<D> is convertible to shared<B>, where D is a class (or struct) derived

   6.  * from B. The following class hierarchy is used to demonstrate the concept.

   7.  */

   8. class Item

   9. {

  10.     std::string title_;

  11. public:

  12.     Item(const std::string& title) :

  13.         title_(title)

  14.     {

  15.     }

  16.     virtual ~Item()

  17.     {

  18.     }

  19. 

  20.     virtual std::string Description() const = 0;

  21.     std::string Title() const

  22.     {

  23.         return title_;

  24.     }

  25. };

  26. 

  27. class Book: public Item

  28. {

  29.     int pages_;

  30. public:

  31.     Book(const std::string& title, int pages) :

  32.         Item(title), pages_(pages)

  33.     {

  34.     }

  35. 

  36.     virtual std::string Description() const

  37.     {

  38.         return "Book: " + Title();

  39.     }

  40.     int Pages() const

  41.     {

  42.         return pages_;

  43.     }

  44. };

  45. 

  46. class DVD: public Item

  47. {

  48.     int tracks_;

  49. public:

  50.     DVD(const std::string& title, int tracks) :

  51.         Item(title), tracks_(tracks)

  52.     {

  53.     }

  54. 

  55.     virtual std::string Description() const

  56.     {

  57.         return "DVD: " + Title();

  58.     }

  59.     int Tracks() const

  60.     {

  61.         return tracks_;

  62.     }

  63. };

  64. 

  65. /*

  66.  * output:

  67.  * Book: Effective STL

  68.  * DVD: Left of the Middle

  69.  */

  70. int main()

  71. {

  72.     std::vector<std::tr1::shared_ptr<Item> > items;

  73.     items.push_back(std::tr1::shared_ptr<Book>(new Book("Effective STL", 400)));

  74.     items.push_back(std::tr1::shared_ptr<DVD>(new DVD("Left of the Middle", 14)));

  75. 

  76.     for (std::vector<std::tr1::shared_ptr<Item> >::const_iterator it =

  77.             items.begin(); it != items.end(); ++it)

  78.         std::cout << (*it)->Description() << std::endl;

  79. 

  80.     return 0;

  81. }

12.dynamic_cast,使用dynamic_pointer_cast将基类向下转型为子类

   1. #include <iostream>

   2. #include <tr1/memory>

   3. #include <vector>

   4. 

   5. /*shared_ptr can work with class hierarchies, so that shared<D> is convertible to shared<B>, where D is a class (or struct) derived

   6.  * from B. The following class hierarchy is used to demonstrate the concept.

   7.  */

   8. class Item

   9. {

  10.     std::string title_;

  11. public:

  12.     Item(const std::string& title) :

  13.         title_(title)

  14.     {

  15.     }

  16.     virtual ~Item()

  17.     {

  18.     }

  19. 

  20.     virtual std::string Description() const = 0;

  21.     std::string Title() const

  22.     {

  23.         return title_;

  24.     }

  25. };

  26. 

  27. class Book: public Item

  28. {

  29.     int pages_;

  30. public:

  31.     Book(const std::string& title, int pages) :

  32.         Item(title), pages_(pages)

  33.     {

  34.     }

  35. 

  36.     virtual std::string Description() const

  37.     {

  38.         return "Book: " + Title();

  39.     }

  40.     int Pages() const

  41.     {

  42.         return pages_;

  43.     }

  44. };

  45. 

  46. class DVD: public Item

  47. {

  48.     int tracks_;

  49. public:

  50.     DVD(const std::string& title, int tracks) :

  51.         Item(title), tracks_(tracks)

  52.     {

  53.     }

  54. 

  55.     virtual std::string Description() const

  56.     {

  57.         return "DVD: " + Title();

  58.     }

  59.     int Tracks() const

  60.     {

  61.         return tracks_;

  62.     }

  63. };

  64. 

  65. /* To convert back, from shared_ptr<B> to shared_ptr<D>, where D is a class (or structure) derived from B,

  66.  * you can use the cast function std::tr1::dynamic_pointer_cast.

  67.  *

  68.  * output:

  69.  * spi counter: 1

  70.  * Left of the Middle, 14 tracks

  71.  * spi counter: 2

  72.  * spb counter: 0

  73.  * spd counter: 2

  74.  */

  75. int main()

  76. {

  77.     std::tr1::shared_ptr<Item> spi(new DVD("Left of the Middle", 14));

  78.     std::cout << "spi counter: " << spi.use_count() << std::endl;

  79.     std::tr1::shared_ptr<Book> spb = std::tr1::dynamic_pointer_cast<Book>(spi);

  80.     if (spb)

  81.         std::cout << spb->Title() << ", " << spb->Pages() << " pages" << std::endl;

  82. 

  83.     std::tr1::shared_ptr<DVD> spd = std::tr1::dynamic_pointer_cast<DVD>(spi);

  84.     if (spd)

  85.         std::cout << spd->Title() << ", " << spd->Tracks() << " tracks"    << std::endl;

  86. 

  87.     std::cout << "spi counter: " << spi.use_count() << std::endl;

  88.     std::cout << "spb counter: " << spb.use_count() << std::endl;

  89.     std::cout << "spd counter: " << spd.use_count() << std::endl;

  90. 

  91.     return 0;

  92. }

13.static cast,使用static_pointer_cast将void转型为char,观察引用计数的变化

   1. #include <iostream>

   2. #include <tr1/memory>

   3. #include <vector>

   4. 

   5. /* A second cast function is std::tr1::static_pointer_cast. It returns an empty shared_ptr if the original object is empty,

   6.  * or a shared_ptr<T> object that owns the resource that is owned by the original object. The expression static_cast<T*>(r.get())

   7.  * must be valid.

   8.  *

   9.  * In the next sample, a vector holds shared_ptr to void. The first element is statically cast to shared_ptr<char>.

  10.  * The cast is valid as long as the source is not empty, regardless of whether the types are compatible or not.

  11.  *

  12.  * output:

  13.  * after creating the shared pointer

  14.  * -1    sp1 counter: 1

  15.  * after adding to the vector

  16.  * -2    sp1 counter: 2

  17.  * A

  18.  * after casting

  19.  * -3    sp1 counter: 3

  20.  * -4    spc counter: 3

  21.  */

  22. int main()

  23. {

  24.     std::vector<std::tr1::shared_ptr<void> > items;

  25.     std::tr1::shared_ptr<char> sp1(new char('A'));

  26.     std::tr1::shared_ptr<short> sp2(new short(66));

  27.     std::cout << "after creating the shared pointer" << std::endl;

  28.     std::cout << "-1    sp1 counter: " << sp1.use_count() << std::endl;

  29.     items.push_back(sp1);

  30.     items.push_back(sp2);

  31.     std::cout << "after adding to the vector" << std::endl;

  32.     std::cout << "-2    sp1 counter: " << sp1.use_count() << std::endl;

  33.     std::tr1::shared_ptr<char> spc = std::tr1::static_pointer_cast<char>(*(items.begin()));

  34.     if (spc)

  35.         std::cout << *spc << std::endl;

  36.     std::cout << "after casting" << std::endl;

  37.     std::cout << "-3    sp1 counter: " << sp1.use_count() << std::endl;

  38.     std::cout << "-4    spc counter: " << spc.use_count() << std::endl;

  39. 

  40.     return 0;

  41. }

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. /* To modify the value of the pointer object the const specifier must be removed. This is shown below.

   5.  *

   6.  * output:

   7.  * csp counter: 1

   8.  * 15

   9.  * 15

  10.  * csp counter: 2

  11.  * sp counter: 2

  12.  */

  13. int main()

  14. {

  15.     std::tr1::shared_ptr<const int> csp(new int(5));

  16.     std::cout << "csp counter: " << csp.use_count() << std::endl;

  17. 

  18.     std::tr1::shared_ptr<int> sp = std::tr1::const_pointer_cast<int>(csp);

  19.     *sp += 10;

  20. 

  21.     std::cout << *csp << std::endl;

  22.     std::cout << *sp << std::endl;

  23. 

  24.     std::cout << "csp counter: " << csp.use_count() << std::endl;

  25.     std::cout << "sp counter: " << sp.use_count() << std::endl;

  26. 

  27.     return 0;

  28. }

15.weak_ptr的lock() 类似于shared_ptr的get()

   1. #include <iostream>

   2. #include <tr1/memory>

   3. 

   4. /* The major weakness of shared_ptr is that it cannot detect cyclic dependencies. In this case, the reference counter is incremented

   5.  * more than it should actually be, so that the resources are no longer released when the shared pointer objects go out of scope.

   6.  * 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

   7.  * affect the reference counter; it is a "weak reference." When the last shared_ptr that owns the resource referred by a weak_ptr,

   8.  * 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

   9.  * function expired() that returns true if the pointer was marked as invalid.

  10.  */

  11. 

  12. /* Even though function get() (that provides direct access to the wrapped pointer) is available, it's not recommended to use it even

  13.  * in single-threaded applications. The safe alternative is function lock() that returns a shread_ptr sharing the resource pointed by

  14.  * the weak pointer.*/

  15. void show(const std::tr1::weak_ptr<int>& wp)

  16. {

  17.     std::tr1::shared_ptr<int> sp = wp.lock();

  18.     std::cout << *sp << std::endl;

  19. }

  20. 

  21. /*

  22.  * output:

  23.  * 44

  24.  * expired : true

  25.  */

  26. int main()

  27. {

  28.     std::tr1::weak_ptr<int> wp;

  29.     {

  30.         std::tr1::shared_ptr<int> sp(new int(44));

  31.         wp = sp;

  32.         show(wp);

  33.     }

  34.     std::cout << "expired : " << std::boolalpha << wp.expired() << std::endl;

  35. 

  36.     return 0;

  37. }

16.一个使用shared_ptr和weak_ptr的二叉树数据结构示例

   1. #include <iostream>

   2. #include <tr1/memory>

   3. 

   4. /* The following sample shows such a tree, but uses a weak_ptr to solve the cyclic dependency.*/

   5. class Node

   6. {

   7.     std::string value_;

   8.     std::tr1::shared_ptr<Node> left_;

   9.     std::tr1::shared_ptr<Node> right_;

  10.     std::tr1::weak_ptr<Node> parent_;

  11. 

  12. public:

  13.     Node(const std::string value) :

  14.         value_(value)

  15.     {

  16.     }

  17. 

  18.     std::string Value() const

  19.     {

  20.         return value_;

  21.     }

  22.     std::tr1::shared_ptr<Node> Left() const

  23.     {

  24.         return left_;

  25.     }

  26.     std::tr1::shared_ptr<Node> Right() const

  27.     {

  28.         return right_;

  29.     }

  30.     std::tr1::weak_ptr<Node> Parent() const

  31.     {

  32.         return parent_;

  33.     }

  34. 

  35.     void SetParent(std::tr1::shared_ptr<Node> node)

  36.     {

  37.         parent_.reset();

  38.         parent_ = node;

  39.     }

  40. 

  41.     void SetLeft(std::tr1::shared_ptr<Node> node)

  42.     {

  43.         left_.reset();

  44.         left_ = node;

  45.     }

  46. 

  47.     void SetRight(std::tr1::shared_ptr<Node> node)

  48.     {

  49.         right_.reset();

  50.         right_ = node;

  51.     }

  52. };

  53. 

  54. std::string path(const std::tr1::shared_ptr<Node>& item)

  55. {

  56.     std::tr1::weak_ptr<Node> wparent = item->Parent();

  57.     std::tr1::shared_ptr<Node> sparent = wparent.lock();

  58. 

  59.     if (sparent)

  60.     {

  61.         return path(sparent) + "//" + item->Value();

  62.     }

  63. 

  64.     return item->Value();

  65. }

  66. 

  67. /*

  68.  * output:

  69.  * C:/dir1/dir11

  70.  */

  71. int main()

  72. {

  73.     std::tr1::shared_ptr<Node> root(new Node("C:"));

  74. 

  75.     std::tr1::shared_ptr<Node> child1(new Node("dir1"));

  76.     std::tr1::shared_ptr<Node> child2(new Node("dir2"));

  77. 

  78.     root->SetLeft(child1);

  79.     child1->SetParent(root);

  80. 

  81.     root->SetRight(child2);

  82.     child2->SetParent(root);

  83. 

  84.     std::tr1::shared_ptr<Node> child11(new Node("dir11"));

  85. 

  86.     child1->SetLeft(child11);

  87.     child11->SetParent(child1);

  88. 

  89.     std::cout << "path: " << path(child11) << std::endl;

  90. 

  91.     return 0;

  92. }

本文出自 “子 孑” 博客,请务必保留此出处http://zhangjunhd.blog.51cto.com/113473/148628
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: