shared_ptr使用
2013-12-16 15:31
190 查看
1.get() 返回对象指针;use_count() 返回对象的引用计数
2.相比较shared_ptr,auto_ptr在赋值与别人后,是放弃对象引用的。
std::tr1::shared_ptr<int> sp = std::tr1::const_pointer_cast<int>(csp);
#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在赋值与别人后,是放弃对象引用的。
#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构造函数中,行参指定构造对象和析构对象的函数
#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() 返回对象指针,使用->调用成员函数
#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
#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所指向的对象
#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.使用等号赋值
#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要快)
#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, 则删除所指对象。
#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
#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 cf07 ) * 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指针使用(声明基类句柄,创建子类对象)
#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将基类向下转型为子类
#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 { 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_; } }; /* 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,观察引用计数的变化
#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);
#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()
#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的二叉树数据结构示例
#include <iostream> #include <tr1/memory> #include <vector> #include <string> using namespace std; using std::tr1::shared_ptr; using std::tr1::weak_ptr; /* The following sample shows such a tree, but uses a weak_ptr to solve the cyclic dependency.*/ class Node { string value_; shared_ptr<Node> left_; shared_ptr<Node> right_; weak_ptr<Node> parent_; public: Node(const string value):value_(value){} string Value() const { return value_; } shared_ptr<Node> Left() const { return left_; } shared_ptr<Node> Right() const { return right_; } weak_ptr<Node> Parent() const { return parent_; } void SetParent(shared_ptr<Node> node) { parent_.reset(); parent_ = node; } void SetLeft(shared_ptr<Node> node) { left_.reset(); left_ = node; } void SetRight(shared_ptr<Node> node) { right_.reset(); right_ = node; } }; string path(const shared_ptr<Node>& item) { weak_ptr<Node> wparent = item->Parent(); shared_ptr<Node> sparent = wparent.lock(); if (sparent) { return path(sparent) + "\\" + item->Value(); } return item->Value(); } /* * output: * C:\dir1\dir11 */ int main() { shared_ptr<Node> root(new Node("C:")); shared_ptr<Node> child1(new Node("dir1")); shared_ptr<Node> child2(new Node("dir2")); root->SetLeft(child1); child1->SetParent(root); root->SetRight(child2); child2->SetParent(root); shared_ptr<Node> child11(new Node("dir11")); child1->SetLeft(child11); child11->SetParent(child1); cout << "path: " << path(child11) << endl; return 0; }
相关文章推荐
- 【C++标准模板库笔记2】智能指针shared_ptr的简单使用
- 有关shared_ptr的使用总结
- C++ std::tr1::shared_ptr使用
- Boost:使用shared_array和shared_ptr
- shared_ptr使用
- shared_ptr 两种常见的使用方式 (1)
- Item 20: 使用std::weak_ptr替换会造成指针悬挂的类std::shared_ptr指针
- boost.shared_ptr源码整理和使用说明
- C++11中使用shared_ptr和unique_ptr管理动态数组
- c++中智能指针auto_ptr与shared_ptr的使用方法
- Boost:使用shared_ptr封装资源句柄
- 智能指针tr1::shared_ptr、boost::shared_ptr使用
- [C++]Shared_ptr使用详解&&实现链表
- utilities(C++)——单例(Singleton) (使用智能指针 shared_ptr)
- Item 19: 使用srd::shared_ptr来管理共享所有权的资源
- 非动态生成对象使用shared_ptr
- C++:智能指针-TR1的shared_ptr和weak_ptr使用介绍
- C++11 shared_ptr 智能指针 的使用,避免内存泄露
- 记录以下boost::shared_ptr的一个使用细节
- C++ TR1 智能指针shared_ptr的使用(转)