//
#include "stdafx.h"
#include
#include
#include
#include
using namespace std;//名字空间,不然使用的时候写std::shared_ptr
int main()
{
//1:智能指针的定义与初始化;
shared_ptr pint1;//定义,不初始化就是一个空指针
shared_ptr pint2 = make_shared();//默认初始化 int默认是0
shared_ptr pint3 = make_shared(44);//值初始化
shared_ptr pstr1 = make_shared(10, 'a');//用string的某一个重载构造函数初始化
auto pVecString1 = make_shared>();//auto也可以
//pint2 = new int(1024);
pint2.reset(new int(1024));//让pint2指向一个新对象,计数器-1,如有必要,释放原内存,新计数器+1
//2:shared_ptr与unique_ptr共有的操作
int * pint4 = pint2.get();//get()将返回一个int*类型的指针,注意不能释放掉pint4所指向的空间,不然会使pint2失效
swap(pint2, pint3);//或者
pint2.swap(pint3);//交换两个指针
//3:shared_ptr独有的操作
make_shared(5);//构造shared_ptr的函数,返回值是shared_ptr
bool isUnique = pint3.unique();//判断pint3是不是唯一指向这个对象的指针 这个例子中返回false
int useCount = pint3.use_count();//返回指向pint3指向对象的所有指针的个数 这个例子中返回1
//4:直接管理内存
string *ps1 = new string;//使用string的默认初始化构造函数
string *ps2 = new string();//使用string的""值初始化函数,只不过这个值是空值。
//我觉得上面这两句的概念不一样吧,但结果是一样的,都是空string。
int *pi1 = new int;//默认初始化 pi1指向的值未定义,int的默认初始化不会为它赋值,string的默认初始化为自己赋值为空。
int *pi2 = new int();//值初始化,pi2指向的值是0
auto pin = new auto(5);//可以推测出pin的类型是int *
const int *pci = new const int(1024);//动态分配的const必须初始化,const int *pci = new const int;是错误的
const string *pcsi = new const string;//默认是空串 这是可以的
int *p2 = new(nothrow)int;//相当于传递给new一个参数 如果内存没空间了 返回一个空指针,而不是报错 头文件#include
delete ps1;//释放内存,但ps1变成空悬指针,指向的地方没有东西。
ps1 = nullptr;//重置指针为空,这是一种保护方式,
//5.shared_ptr new 结合使用
shared_ptr pdou1(new double(10.8));//之后不用delete来释放内存,pdou1在作用域结束时会释放内存
//注意shared_ptr pdou1=new double(10.8);的写法是错误的,因为shared_ptr的构造函数是explicit
if (!pstr1.unique())
pstr1.reset(new string(*pstr1));
*pstr1 += "hellpo";
//上面这三行代码的含义是:pstr1是我上面定义的智能指针,假设现在我想通过这个智能指针改变所指向对象的值,
//但是如果有其他智能指针也指向这个对象,那我就间接的把其他智能指针的对象也改变了,
//因为这些智能指针所指都是同一个对象。所以,判断一下是否自己是唯一指针,如果不是唯一指针的话,
//让pstr1重新指向一个拥有同一个对象值的string,相当于又开辟了一块内存。再改变新的对象.
//6.智能指针与异常
//如果在我写的这整段程序的这一位置出现了异常,那么最后的return0和}不会执行,即使这样,shared_ptr所指的内存也能自动释放,
//但是new出来的内存,没碰到delete就不能被释放. 优点:使用智能指针可以避免内存泄漏!
//7.unique_ptr 指向唯一的对象 不能拷贝 unique_ptr unPin1(p2);是错误的 不能赋值 unPin1=p2也是错误的
unique_ptr unPin1(new int(48));//unique_ptr un(d);指向T对象,用类型为D的对象d来代替delete
//unPin1 = nullptr;//释放对象 或者nuPin1.reset(nullptr);
//unPin1.release();//返回原指针,同时原指针放弃对指针的控制权,并置空,但是这种写法是不正确的,因为内存不会释放!!!
//unPin1.reset();//unPin1.reset(p);释放并指向内置指针p
//用release 和 reset解决unique_ptr不能拷贝和赋值的情况,上面几行我注释掉,因为我要运行,不想让它变空
unique_ptr unPin2(new int(53));
unique_ptr unPin3(unPin2.release());//这样就可以拷贝了
unPin1.reset(unPin3.release());//这样就可以赋值了
int* unPin1copy = unPin1.release();//release一定要赋值 不然就没有释放内存 返回类型int*
//8.weak_ptr
auto p = make_shared(76);
weak_ptr wp(p);//weak_ptr用shared_ptr来构造,不增加引用计数,不控制对象的生存期 “弱”
wp = p;//支持赋值
wp.reset();//指针置空
wp.use_count();//返回这个对象shared_ptr的数量
wp.expired();//use_count为0时返回true
wp.lock();//返回一个shared_ptr 可以是空 或者是指向某对象的//weak_ptr不能用来访问对象,一定是用lock()
if(shared_ptr np=wp.lock()){}
return 0;
}
#pragma once
#include
#include
#include
#include
#include"StrBlobPtr.h"
using namespace std;//不写名字空间的话 好麻烦
class StrBlob {
public:
typedef std::vector::size_type size_type;
StrBlob():data(std::make_shared>()){}
StrBlob(std::initializer_list &l):data(std::make_shared>(l)){}
size_type size()const { return data->size(); }
bool empty()const { return data->empty(); }
void push_back(std::string &s) { data->push_back(s); }
void pop_back(){
check(0, "popback on empty StrBlob");
data->pop_back();
}
std::string &front() {
check(0, "front on empty StrBlob");
return (*data)[0];
}
std::string &back() {
check(0, "back on empty StrBlob");
return (*data)[data->size() - 1];
}
const string &front()const{}//重载const类型
const string &back()const{}//同上
friend class StrBlobPtr;
StrBlobPtr begin() {
return StrBlobPtr(*this);
}
StrBlobPtr end() {
StrBlobPtr p = StrBlobPtr(*this, data->size());
return p;
}
private:
std::shared_ptr> data;
void check(size_type i,const std::string &msg)const{
//检查元素是否存在
if (i >= data->size())
throw out_of_range(msg);
}
};
#pragma once
#include
#include
#include
#include
using namespace std;
class StrBlobPtr {
public:
StrBlobPtr():cur(0){}
StrBlobPtr(StrBlob &rhs,size_t sz=0):wptr(rhs.data),cur(sz){}
private:
weak_ptr > wptr;
size_t cur;
shared_ptr> check(size_t i, const string &msg){
//check函数返回一个智能指针 如果不存在 回抛出异常
auto p = wptr.lock();
if (!p)
throw runtime_error("unbound");
if (i >= p->size())
throw out_of_range("msg");
return p;
}
};