C++编程笔记(智能指针学习)
scoped_ptr
- 拷贝构造和 =赋值操作均为私有,不允许
- 内部重载了解引用(*)操作符和 ->操作符,操作与普通指针无异
用例
//拷贝构造和赋值操作均为私有 利用模板
scoped_ptr<string> p(new string("hello world"));//初始化一个指向string的指针
cout << *p << '\n' << p->size() << '\n';//用法与普通指针一致
assert(p);//用于判断指针是否为空
p.reset();//指针重置
//p++;//错误 智能指针只有* 和 ->操作符
unique_ptr
- 与scoped_ptr极为相似
//与scoped极为相似
void testUnique() {
//Unique基本功能与scope相同
unique_ptr<int> p(new int);
int *a = new int(123);
assert(p);//测试指针是否有效;
p.reset(a); //利用指针,使得指针重新指向一个新的对象(类型必须与初始化时相同)
*p = 100;
Show<int>(*p);
p.reset();//置空
//工厂函数
//比使用new更为安全,且效率不低
p = std::make_unique<int>(10);
//p = boost::make_unique<int>(10); /scoped_ptr没有这个函数,因为拷贝构造私有
Show(*p);
}
shared_ptr
- 可以拷贝,可以赋值(=)
案例
void testShared() {
boost::shared_ptr<int> p(new int);
*p = 100;
boost::shared_ptr<int> p1(p);
cout << "引用是否唯一:" << p.unique() << endl;//是否唯一,1为真,0为假
p1.reset();//重置p1
cout << "(reset后)引用是否唯一:" << p.unique() << endl;//是否唯一,1为真,0为假
//p1.reset(new int);
boost::shared_ptr<vector<int>> sp = boost::make_shared<vector<int>>(10, 2);//初始化添加10个2
//boost::shared_ptr<int[]>sps=boost::make_shared<int[]>(10);大小为10的数组
(*sp).push_back(10);
sp->push_back(20);
for (int &x: *sp) {
cout << x << '\t';
}
}
智能指针简单应用
void myfclose(ifstream *ifs) {
cout << "文件关闭\n";
ifs->close();
}
ifstream *myfopen(const char *path) {
cout << path << "打开\n";
return new ifstream(path, ios::in);
}
void testShared1() {
//ifstream *fs = myfopen("./bridge.cpp");
//巧用删除器,当智能指针销毁时会调用myfclose函数
boost::shared_ptr<ifstream> fp(myfopen("/home/lhh/boost_1_77_0/LICENSE_1_0.txt"), myfclose);
char buf;
while ((buf = fp->get()) != EOF) {
cout << buf;
}
}
上述案例运用了shared_ptr的包含了删除器的构造函数
template<class Y, class D>
shared_ptr( Y * p, D d ): px( p ), pn( p, static_cast< D&& >( d ) )
{
boost::detail::sp_deleter_construct( this, p );
}
//D可以是个函数对象或者函数指针,只要能是的D(...)合法就没问题,离开作用域时,函数会调用D
智能指针简单应用
//使用智能指针指向数组
unique_ptr<char[]> p= make_unique<char[]>(50);
- 通常我们都是使用
unique_ptr
管理数组,因为在C++17之前,shared_ptr
还无法正确的释放数组资源,需要自己定义删除器,并且unique_ptr
重载了下标运算符[]
,并且可以正确释放数组资源