c++/c 标准库 shared_ptr weak_ptr

/*
 * 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> sp						create 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 = sp2								assignment,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
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值