您的位置:首页 > 编程语言 > C语言/C++

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

2017-06-25 08:42 405 查看
//

#include "stdafx.h"
#include <memory>
#include <string>
#include <vector>
#include<new>
using namespace std;//名字空间,不然使用的时候写std::shared_ptr

int main()
{
//1:智能指针的定义与初始化;
shared_ptr<int> pint1;//定义,不初始化就是一个空指针
shared_ptr<int> pint2 = make_shared<int>();//默认初始化 int默认是0
shared_ptr<int> pint3 = make_shared<int>(44);//值初始化
shared_ptr<string> pstr1 = make_shared<string>(10, 'a');//用string的某一个重载构造函数初始化
auto pVecString1 = make_shared<vector<string>>();//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<int>(5);//构造shared_ptr的函数,返回值是shared_ptr<int>
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<new>
delete ps1;//释放内存,但ps1变成空悬指针,指向的地方没有东西。
ps1 = nullptr;//重置指针为空,这是一种保护方式,

//5.shared_ptr new 结合使用
shared_ptr<double> pdou1(new double(10.8));//之后不用delete来释放内存,pdou1在作用域结束时会释放内存
//注意shared_ptr<double> 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<int> unPin1(p2);是错误的 不能赋值 unPin1=p2也是错误的
unique_ptr<int> unPin1(new int(48));//unique_ptr<T,D> 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<int> unPin2(new int(53));
unique_ptr<int> unPin3(unPin2.release());//这样就可以拷贝了
unPin1.reset(unPin3.release());//这样就可以赋值了
int* unPin1copy = unPin1.release();//release一定要赋值 不然就没有释放内存 返回类型int*

//8.weak_ptr
auto p = make_shared<int>(76);
weak_ptr<int> 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<int> np=wp.lock()){}

return 0;
}
#pragma once
#include <memory>
#include <string>
#include <vector>
#include<initializer_list>
#include"StrBlobPtr.h"

using namespace std;//不写名字空间的话 好麻烦
class StrBlob {
public:
typedef std::vector<std::string>::size_type size_type;
StrBlob():data(std::make_shared<std::vector<std::string>>()){}
StrBlob(std::initializer_list<std::string> &l):data(std::make_shared<std::vector<std::string>>(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<std::vector<std::string>> data;
void check(size_type i,const std::string &msg)const{
//检查元素是否存在
if (i >= data->size())
throw out_of_range(msg);
}
};
#pragma once
#include <memory>
#include <string>
#include <vector>
#include<initializer_list>

using namespace std;
class StrBlobPtr {
public:
StrBlobPtr():cur(0){}
StrBlobPtr(StrBlob &rhs,size_t sz=0):wptr(rhs.data),cur(sz){}
private:
weak_ptr<vector<string> > wptr;
size_t cur;

shared_ptr<vector<string>> 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;

}

};
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签:  智能指针