shared_ptr使用

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

#include 
#include  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 sp1(new Foo);sp1->print();cout << "sp1 pointer: " << sp1.get() << endl;shared_ptr 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 
#include 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 ap1(new Foo);ap1->print(); cout << "ap1 pointer: " << ap1.get() << endl;shared_ptr sp1(ap1); // 注意这里是shared_ptrsp1->print(); cout << "ap1 pointer: " << ap1.get() << endl;cout << "sp1 pointer: " << sp1.get() << endl;return 0; 
}
3.在shared_ptr构造函数中,行参指定构造对象和析构对象的函数
#include 
#include  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 ptr(FooHandler::alloc(), FooHandler::free); ptr->print();return 0; 
}
4.get() 返回对象指针,使用->调用成员函数
#include 
#include  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 sp(new Foo);Foo* f = sp.get();if (f != NULL)f->print();return 0;
}
5.get() 返回对象指针,if判断是否为null
#include 
#include  
#include 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& ptr){ptr != NULL ? cout << "not empty" << endl: cout << "is empty" << endl;}
};/*
* output:
* is empty
* not empty
*/
int main()
{shared_ptr sp1;shared_ptr sp2(new string("demo"));PtrUtil::is_empty(sp1);PtrUtil::is_empty(sp2);return 0;
}
6.swap() 交换两个shared_ptr所指向的对象
#include 
#include 
#include 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 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 sp1;shared_ptr 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 
#include 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 sp1(new int(1)); cout << "sp1 = " << *sp1 << endl;shared_ptr sp2(new int(2));cout << "sp2 = " << *sp2 << endl;sp1 = sp2;cout << "sp1 = " << *sp1 << endl;return 0;
}
8.unique() 判断当前对象的引用计数==1? ( 比调用use_count()==1要快
#include 
#include 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 sp1(new string("marius bancila")); cout << "unique : " << std::boolalpha << sp1.unique() << endl; cout << "counter : " << sp1.use_count() << endl;shared_ptr sp2(sp1); cout << "unique : " << std::boolalpha << sp1.unique() << endl; cout << "counter : " << sp1.use_count() << endl;return 0; 
}
9.reset() 清空当前shared指针,并将所有基于该指针创建的shared指针的引用计数减1, 如果为0, 则删除所指对象。
#include 
#include  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 1shared_ptr sp1(new Foo);cout << "counter sp1: " << sp1.use_count() << endl;shared_ptr sp2(sp1);shared_ptr 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 emptysp1.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  
#include  
#include  
#include 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 double_it(const shared_ptr& 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 > numbers;numbers.push_back(shared_ptr(new int(1))); numbers.push_back(shared_ptr(new int(2))); numbers.push_back(shared_ptr(new int(3))); cout << "initially" << endl; for (vector >::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 >::const_iterator it = numbers.begin(); it != numbers.end(); ++it) cout << **it << " (counter = " << (*it).use_count() << ")" << endl;return 0; 
}
11.多态情况下的shared指针使用(声明基类句柄,创建子类对象)
#include  
#include  
#include 
#include using namespace std;
using std::tr1::shared_ptr;/*shared_ptr can work with class hierarchies, so that shared is convertible to shared, 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 > items;items.push_back(shared_ptr(new Book("Effective STL", 400)));items.push_back(shared_ptr(new DVD("Left of the Middle", 14)));for (vector >::const_iterator it = items.begin(); it != items.end(); ++it)cout << (*it)->Description() << endl;return 0;
}
12.dynamic_cast,使用dynamic_pointer_cast将基类向下转型为子类
#include 
#include 
#include using namespace std;
using std::tr1::shared_ptr;/*shared_ptr can work with class hierarchies, so that shared is convertible to shared, 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 to shared_ptr, 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 spi(new DVD("Left of the Middle", 14));cout << "spi counter: " << spi.use_count() << endl;shared_ptr spb = std::tr1::dynamic_pointer_cast(spi);if (spb != NULL)cout << spb->Title() << ", " << spb->Pages() << " pages" << endl;shared_ptr spd = std::tr1::dynamic_pointer_cast(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 
#include  
#include 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 object that owns the resource that is owned by the original object. The expression static_cast(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.* 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 > items;shared_ptr sp1(new char('A'));shared_ptr 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 spc = tr1::static_pointer_cast(*(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 csp,可以声明
std::tr1::shared_ptr sp = std::tr1::const_pointer_cast(csp);
#include 
#include 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 csp(new int(5));cout << "csp counter: " << csp.use_count() << endl;shared_ptr sp = std::tr1::const_pointer_cast(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  
#include 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& wp)
{shared_ptr sp = wp.lock();cout << *sp << endl; 
}/** output:* 44* expired : true*/
int main()
{weak_ptr wp;{shared_ptr sp(new int(44));wp = sp;show(wp);}cout << "expired : " << boolalpha << wp.expired() << endl;return 0;
}
16.一个使用shared_ptr和weak_ptr的二叉树数据结构示例
#include  
#include  
#include 
#include 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 left_;shared_ptr right_;weak_ptr parent_;
public:Node(const string value):value_(value){}string Value() const { return value_; }shared_ptr Left() const { return left_; } shared_ptr Right() const { return right_; }weak_ptr Parent() const { return parent_; }void SetParent(shared_ptr node){parent_.reset();parent_ = node;}void SetLeft(shared_ptr node){left_.reset();left_ = node;}void SetRight(shared_ptr node){right_.reset();right_ = node;}
};string path(const shared_ptr& item)
{weak_ptr wparent = item->Parent();shared_ptr sparent = wparent.lock();if (sparent){return path(sparent) + "\\" + item->Value(); }return item->Value();
}/** output:* C:\dir1\dir11
*/
int main()
{shared_ptr root(new Node("C:"));shared_ptr child1(new Node("dir1"));shared_ptr child2(new Node("dir2"));root->SetLeft(child1);child1->SetParent(root);root->SetRight(child2);child2->SetParent(root);shared_ptr child11(new Node("dir11"));child1->SetLeft(child11);child11->SetParent(child1);cout << "path: " << path(child11) << endl;return 0;
}


本文来自互联网用户投稿,文章观点仅代表作者本人,不代表本站立场,不承担相关法律责任。如若转载,请注明出处。 如若内容造成侵权/违法违规/事实不符,请点击【内容举报】进行投诉反馈!

相关文章