/*
* 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中成功
}
c++/c 标准库 shared_ptr weak_ptr
最新推荐文章于 2022-08-25 11:29:43 发布