智能指针——c++primer第五版12章——个人总结


//

#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;

	}

};



你可能感兴趣的:(c++)