这个写的更好! https://www.cnblogs.com/TenosDoIt/p/3456704.html
#auto_ptr
auto_ptr是C++标准库中()为了解决资源泄漏的问题提供的一个智能指针类模板(注意:这只是一种简单的智能指针)
auto_ptr的实现原理其实就是RAII,在构造的时候获取资源,在析构的时候释放资源,并进行相关指针操作的重载,使用起来就像普通的指针。
对于编译器来说,智能指针实质是一个栈对象,而并非指针类型。
智能指针通过构造函数获取堆内存的管理所有权,而在其生命期结束时,再通过析构函数释放由它所管理的堆内存。
所有智能指针都重载了“operator->”操作符,直接返回对象的引用,用以操作对象。访问智能指针原来的方法则使用“.”操作符。
访问智能指针包含的裸指针则可以用get()函数。
由于智能指针是一个对象,所以if(spObject)永远为真。要判断智能指针的裸指针是否为空,需要这样判断:if(spObject.get())。
智能指针包含了reset()方法,如果不传递参数(或传递NULL),则智能指针会释放当前管理的内存。如果传递一个对象,则智能指针会释放当前对象,来管理新传入的对象。
std::auto_ptr<ClassA> pa(new ClassA);
#include<iostream>
#include<memory>
using namespace std;
class Int
{
public:
Int(int nValue = 0)
{
m_nValue = nValue;
std::cout << "Constructor: " << m_nValue << std::endl;
}
~Int()
{
std::cout << "Destructor: " << m_nValue << std::endl;
}
void PrintValue()
{
std::cout << "PrintValue: " <<m_nValue<< std::endl;
}
void SetValue(int nSetValue)
{
m_nValue = nSetValue;
}
private:
int m_nValue;
};
void TestAuto_Ptr1()
{
std::auto_ptr<Int> spInt(new Int(10)); // 创建对象 初值为使用 10 的Int对象
if (spInt.get()) // 判断智能指针是否为空
{
spInt->PrintValue(); // 使用operator->调用智能指针对象的函数
spInt.get()->SetValue(20); // 使用get()返回裸指针,然后通过裸指针调用的成员函数
spInt->PrintValue(); // 再次打印,检验上步赋值成功
(*spInt).SetValue(30); // 使用operator*返回智能指针内部对象,然后用“.”调用智能指针对象中的函数
spInt->PrintValue(); // 再次打印,表明上步赋值成功
}
// !!!spInt栈对象结束生命期,随之析构堆对象Int(10),同时释放内存资源, 不用的显示的调用 delete
}
int main()
{
TestAuto_Ptr1();
return 0;
}
//执行结果如下:
/*
Constructor: 10
PrintValue: 10
PrintValue: 20
PrintValue: 30
Destructor: 30
*/
总结:关于std::auto_ptr的使用,请注意以下几点:
(1)尽量不要使用“operator=”(如果使用了,请不要再使用先前对象)。
(2)记住release()函数不会释放对象,仅仅归还所有权。
(3)std::auto_ptr最好不要当成参数传递(读者可以自行写代码确定为什么不能)。
(4)由于std::auto_ptr的“operator=”问题,由其管理的对象不能放入std::vector等容器中。
(5)auto_ptr存储的指针应该为NULL或者指向动态分配的内存块。
(6)auto_ptr存储的指针应该指向单一物件(是new出来的,而不是new[]出来的)。
(7)两个auto_ptr对象不会同时指向同一块内存块(要明白两个auto_ptr对象赋值会发生什么)。
#shared_ptr
boost::shared_ptr是可以共享所有权的智能指针
shared_ptr非常有价值、非常重要、非常有用
#include <string>
#include <iostream>
#include <boost/shared_ptr.hpp>
class implementation
{
public:
~implementation() { std::cout <<"destroying implementation\n"; }
void do_something() { std::cout << "did something\n"; }
};
void test()
{
boost::shared_ptr<implementation> sp1(new implementation());
std::cout<<"The Sample now has "<<sp1.use_count()<<" references\n";
boost::shared_ptr<implementation> sp2 = sp1; // 智能指针的复制, 同事指向一个对象
std::cout<<"The Sample now has "<<sp2.use_count()<<" references\n";
sp1.reset();
std::cout<<"After Reset sp1. The Sample now has "<<sp2.use_count()<<" references\n";
sp2.reset();
std::cout<<"After Reset sp2.\n";
}
int main()
{
test();
return 0;
}
sp1对implementation对象进行管理,其引用计数为1
增加sp2对implementation对象进行管理,其引用计数增加为2
sp1释放对implementation对象进行管理,其引用计数变为1
sp2释放对implementation对象进行管理,其引用计数变为0,该对象被自动删除
程序输出
The Sample now has 1 references
The Sample now has 2 references
After Reset sp1. The Sample now has 1 references
destroying implementation // 此时执行了销毁函数
After Reset sp2.
boost::shared_ptr指针sp1和sp2同时拥有了implementation对象的访问权限,且当sp1和sp2都释放对该对象的所有权时,其所管理的的对象的内存才被自动释放。在共享对象的访问权限同时,也实现了其内存的自动管理。
特点: boost::shared_ptr可以共享对象的所有权
#weak_ptr
weak_ptr是为了配合shared_ptr而引入的一种智能指针,它更像是shared_ptr的一个助手而不是智能指针,因为它不具有普通指针的行为,没有重载operator*和->,它的最大作用在于协助shared_ptr工作,像旁观者那样观测资源的使用情况.
eak_ptr被设计为与shared_ptr共同工作,可以从一个shared_ptr或者另一个weak_ptr对象构造,获得资源的观测权。但weak_ptr没有共享资源,它的构造不会引起指针引用计数的增加。
使用weak_ptr的成员函数use_count()可以观测资源的引用计数, weak_ptr可以使用一个非常重要的成员函数lock()从被观测的shared_ptr获得一个可用的shared_ptr对象,
参考资料
weak_ptr 类: https://msdn.microsoft.com/zh-cn/library/bb982126.aspx