c++/c 标准库 shared_ptr weak_ptr

来源:互联网 发布:网络连接异常 英雄联盟 编辑:程序博客网 时间:2024/06/05 16:17
/* * main.cpp * *  Created on: 2015年1月2日 *      Author: star *///============================================================================// Name        : ff.cpp// Author      : star// Version     :// Copyright   : Your copyright notice// Description : Hello World in C++, Ansi-style//============================================================================#include <iostream>#include <memory>#include <vector>#include <atomic>using namespace std;/* * 多个对象可以拥用一个资源,我们可以看到在赋值等运算,均会共享资源,这个可能并不是我们想要的,有时我们需要对其有所限制,使其难以更改。 * 对于内置类型,我们可以不定义del,但对于数组,用户必须显示定义其删除方法,或调用 库函数 std::defalut_delete<typenama[]>() * 还有一个重要的问题,便是shared_ptr并不是线程安全的,故,我们可以通过原子操作,蔌线程锁来解决这个问题,最后给出的可能用到的基本的原子操作 * shared_ptr<T> spcreate an empty shared pointer * shared_ptr<T> sp(ptr)create a shared pointer owing *ptr,using the default deleter * shared_ptr<T> sp(ptr,del)    create a shared ponter owing * ptr ,using  del as its deleter * shared_ptr<T> sp(ptr,del,ac)  del as deleter, ac as allocator * shared_ptr<T> sp(nullptr)和前相同,只不过初始化为空指针 * shared_ptr<T> sp(nullptr,del) * shared_ptr<T> sp(nullptr,del,ac) * shared_ptr<T> sp(sp2)create an a shared ponter sharing ownership with sp2 * shared_ptr<T> sp(move(sp2))同上,但根据move语义,执行完,sp2指向空。 * shared_ptr<T> sp(sp2,ptr)!!这个东西可能与理解的不是很相同,这个产生的sp与sp2地址并不相同,且sp是在,绑定一个分配子的问题 * shared_ptr<T> sp(wp)create a shared pointer out of weak pointer wp * shared_ptr<T> sp(move(up))a shared pointer out of unique_ptr * shared_ptr<T> sp(move(ap))a shared pointer out of auto_ptr * sp.~shared_ptr()desturctor, calls the deleter if sp owns an object * sp = sp2assignment,sp shares ownership with sp2 afterward,giving up ownership of object previously owned * sp =move(sp2)move assignment,sp2 transfer ownership to sp * sp = move(up) * sp = move(ap) * sp1.swap(sp2)swaps pointer and deleters of sp1 and sp2 * swap(sp1,sp2) * sp.reset()gives up ownership and reintializes the shared pointers as being empty.sp is nullptr * sp.reset(ptr)reset 相比于构造方法,可以直接用于ptr赋值, * sp.reset(ptr,del) * sp.reset(ptr,del,ac) * make_shared<T>(...)这个产生的比较快。 * allocate_shared(ac,...)指定分配子的make_shared<>,第一个参数, * sp.get() * *sp * sp-> * sp.use_count() * sp.unique() * operator bool() * sp1 == sp2, sp1 != sp2 * sp1 < sp1 sp1 >sp2 sp1 <= sp2 sp1 >=sp2 * * static_point_cast<>〉(sp)shared_ptr的static_cast版本。 * dynamic_pointer_cast<>(sp)shared_Ptr特制版本 * const_pointer_cast<>(sp) * get_deleter(sp) 返回deleter 的地址 * os << sp等于 os << sp.get() * sp.owner_before(sp2) * sp.owner_before(wp) * ************************************************************************************ *****************************************weak_ptr*********************************** ************************************************************************************ * 算不上一个真正的智能指针,只能算为shared_ptr<T>的辅助工具。可以共享 share_ptr<T>所指向资源,但并不拥用的。其初始化,基本上只可以从一个shared_ptr进行。 * 另,weak_ptr 没有运算符*和->,故,要取值,必须通过lock()创建一个shared_ptr来调用 * weak_ptr<T> wp一个空的weak_ptr * weak_ptr<T> wp(sp)对共享一个shared_ptr指向的资源 * weak_ptr<T> wp(wp2) * wp.~weak_ptr() * * wp = wp2 * wp = sp * * wp.swap(wp2) * swap(wp1,wp2) * wp.reset() * wp.use_count() * wp.expired()is equiivalent to wp.use_count() == 0,即 * wp.lock() * wp.owner_before(sp) * wp.owner-before(wp) * ******************************************************************************************************** *********************************************可能的原子操作的几个高级接口************************************************* ******************************************************************************************************** * * atomic_is_lock_free(&sp)如果sp是lock free,则返回true * atomic_load(&sp);返回sp * atomic_store(&sp,sp2);sp = sp2 * atomic_exchange(&sp,sp2)sp.swap(sp2) */int main() {shared_ptr<int> sp;shared_ptr<string> sp1(new string("shared_ptr"),[](string* p){cout << "初始化指针删除器\n";});shared_ptr<string> sp4(new string("another shared_ptr"),[](string* a){cout << "sp4 is delete\n";delete a;});sp4 = sp1; //sp4 指向sp1,原sp4 释放cout <<"sp4和sp1共同拥有资源"<<sp1.use_count()<<endl;shared_ptr<string> sp5(sp1,new string("sp5"));cout<<sp5<<" "<<sp1<<" "<<sp4.get()<<endl;//sp5与sp1地址并不同,本质上说此二者并非共享指针,只是一个分配子的问题,sp4与sp1为共享地址cout <<"sp5和sp1指向不同:"<<*sp5<<endl<<*sp1<<endl;cout <<"但引用数却会增加" <<sp5.use_count()<<endl;auto sp6 = make_shared<string>("make_shared");cout << "make_shared:"<<*sp6<<endl;sp.reset(new int(45));cout <<"unique 当引用只有一个时,为true,否则,为false,包含无引用情况:" <<sp.unique()<< " " << sp.use_count()<<endl; // unique 当引用只有一个时,为true,否则,为false,包含无引用情况 //static_pointer_cast<int*>(sp.get());shared_ptr<void> vsp(new int);   //仅可以把void 的转为其他指针。 cout <<"从void转为int*:"<< static_pointer_cast<int*>(vsp)<<endl; cout <<"用sp初始wp之前:"<<sp1.use_count()<<endl; weak_ptr<string> wp; weak_ptr<string> wp1(sp1); cout <<"用sp初始化wp之后,wp和sp的use_count指向是相同,wp由于不拥有资源,故并不会增加资源拥有数量:"<< wp1.use_count() << " "<< sp1.use_count()<<endl; cout << "expired,当无资源时,为1:"<<wp.expired()<<endl; /*  * 对于shared_ptr<T> 若指向一个数组,则必须自定义delete  */ shared_ptr<int>spa(new int[10],[](int* a){ delete []a; }); shared_ptr<int>spa1(new int[10],std::default_delete<int[]>()); /*  * 对于shared_ptr 的一个误用便是同一个分配子,不可分配给两个不同的shared_ptr,如果我们需要共享  * 这个不会报错的,但这个错误很可怕,我们看到两个智能指针指向同一个资源,但是两个对象,这也必须会造成会多次释放的问题,  * 但问题是编译器不能发现这个问题。且gcc编译后运行亦无错,可能是其进行了优化,vs在运行时出错  */#if 0         int* p = new int; shared_ptr<int> spp(p); shared_ptr<int> sppa(p); cout << spp.use_count()<<spp<<endl; cout << sppa.use_count()<<sppa<<endl;#endif /*  * 关于shared_ptr的第二个问题,创建一个类的this指针的shared_ptr<T>类型,我们不可以直接用this去构造,而只能通过类继承 std::enable_shared_from_this<>,  * 在类中使用shared_from_this()来取得  * 但注意,shared_from_this()函数不能用于构造函数。  *  */ struct sc : std::enable_shared_from_this<string>{ vector<shared_ptr<string>> vsp; void add(){ vsp.push_back(shared_from_this());// vsp.push_back(shared_ptr<string>(this)); } }; std::atomic_store(&sp1,sp4); //gcc中这个没有测试成功,vs中成功    }

0 0