《c++ primer》12.1章节
1、智能指针是为了更加安全(防止内存还被引用着就被释放)和方便(不必自己手动释放内存)地使用动态内存(静态内存和栈内存中的对象由编译器创建和销毁,动态内存由程序创建和销毁)而存在。
2、shared_ptr的特点是允许多个指针指向同一个对象。
3、智能指针也是模板,因此要指定类型:
std::shared_ptr<int> p;
4、shared_ptr默认值是nullptr。
5、unique()内存是否被唯一指针引用。
6、use_count()获取引用计数。当引用计数变为0时,shared_ptr会自动释放它管理的对象。
7、不能将普通指针转换成智能指针。
以下写法是错误的:
std::shared_ptr<int> p1 = new int(1024);
new运算符返回的是一个int类型的指针,这里试图将int*普通指针隐式转换成shared_ptr。
正确的写法:
std::shared_ptr<int> p1(new int(1024));
或:
std::shared_ptr<int> p1 = std::make_shared<int>(1024);
8、重设shared_ptr,若再没有其他shared_ptr指向对象则对象释放:reset(),这会让shared_ptr的值设为空。
#define debug qDebug()<<
int main(int argc, char *argv[])
{
std::shared_ptr<int> p1 = std::make_shared<int>(1024);
std::shared_ptr<int> p2 = p1;
debug (p1 == nullptr) << &*p1 << &*p2;
p1.reset();
debug (p1 == nullptr);
debug p2.use_count() << *p2 << &*p2;
}
reset()还可以将一个新的指针赋给shared_ptr,如果原来指向的对象不为空,则被释放:
std::shared_ptr<int> p1 = std::make_shared<int>(1024);
p1.reset(new int(666));
9、get()返回智能指针管理的对象的普通指针,get()的存在是为了向不能使用智能指针的代码传递普通指针。
std::shared_ptr<int> p1 = std::make_shared<int>(1024);
int * p2 = p1.get();
10、不要混用普通指针和智能指针,例:
void debugValue(std::shared_ptr<int> sp)
{
qDebug()<<*sp;
}
#define debug qDebug()<<
int main(int argc, char *argv[])
{
int * p2 = new int(666);
debugValue(std::shared_ptr<int>(p2));
debug *p2;
}
这里传参数的时候创建了一个临时的shared_ptr,引用了p2的地址,当debugValue()执行完了以后会清除该临时变量,作为唯一引用p2地址的shared_ptr被清除时,会释放其引用的对象,p2指向的对象就被释放了。
正确的做法是只使用智能指针:
void debugValue(std::shared_ptr<int> sp)
{
qDebug()<<*sp;
}
#define debug qDebug()<<
int main(int argc, char *argv[])
{
std::shared_ptr<int> p1 = std::make_shared<int>(1024);
debugValue(p1);
if(p1 == nullptr)
debug "p1为空";
else
debug *p1;
}
11、自定义删除器。 shared_ptr在清空所指向的对象时默认调用的是对象的析构函数,如果没有析构函数的对象可以在shared_ptr创建时指定自定义的删除器,如源码所示:
void deleteFun(int *p)
{
qDebug()<<"delete Run";
delete p;
}
#define debug qDebug()<<
int main(int argc, char *argv[])
{
std::shared_ptr<int> p1(new int(1024),deleteFun);
}
这样清除对象时就会调用指定的函数。