智能指针是一个类对象,而非一个指针对象。
原始指针:通过new建立的*指针
智能指针:通过智能指针关键字(unique_ptr, shared_ptr ,weak_ptr)建立的指针
它的一种通用实现方法是采用引用计数的方法。智能指针将一个计数器与类指向的对象相关联,引用计数跟踪共有多少个类对象共享同一指针。
每次创建类的新对象时,初始化指针并将引用计数置为1;
当对象作为另一对象的副本而创建时,拷贝构造函数拷贝指针并增加与之相应的引用计数;
对一个对象进行赋值时,赋值操作符减少左操作数所指对象的引用计数(如果引用计数为减至0,则删除对象),并增加右操作数所指对象的引用计数;这是因此左侧的指针指向了右侧指针所指向的对象,因此右指针所指向的对象的引用计数+1;
调用析构函数时,构造函数减少引用计数(如果引用计数减至0,则删除基础对象)。
unique_ptr
只允许基础指针的一个所有者。 除非你确信需要 shared_ptr,否则请将该指针用作 POCO 的默认选项。 可以移到新所有者,但不会复制或共享。 替换已弃用的auto_ptr。 与 boost::scoped_ptr 比较。 unique_ptr 小巧高效;大小等同于一个指针且支持 rvalue 引用,从而可实现快速插入和对 STL 集合的检索。 头文件:<memory>。 有关更多信息,请参见如何:创建和使用
unique_ptr 实例和unique_ptr
类。
shared_ptr
采用引用计数的智能指针。 如果你想要将一个原始指针分配给多个所有者(例如,从容器返回了指针副本又想保留原始指针时),请使用该指针。 直至所有shared_ptr 所有者超出了范围或放弃所有权,才会删除原始指针。 大小为两个指针;一个用于对象,另一个用于包含引用计数的共享控制块。 头文件:<memory>。 有关更多信息,请参见如何:创建和使用
shared_ptr 实例和shared_ptr
类。
weak_ptr
结合 shared_ptr 使用的特例智能指针。 weak_ptr 提供对一个或多个 shared_ptr 实例拥有的对象的访问,但不参与引用计数。 如果你想要观察某个对象但不需要其保持活动状态,请使用该实例。 在某些情况下,需要断开 shared_ptr 实例间的循环引用。 头文件:<memory>。 有关更多信息,请参见如何:创建和使用共享
weak_ptr 实例和weak_ptr
类。
智能指针的设计原则是在内存和性能上尽可能高效。 例如,unique_ptr 中的唯一数据成员是封装的指针。 这意味着,unique_ptr 与该指针的大小完全相同,不是四个字节就是八个字节。 使用重载了 * 和 -> 运算符的智能指针访问封装指针的速度不会明显慢于直接访问原始指针的速度。同时智能指针不仅在超出控制外围时可以释放内存,在超出范围之前也能释放内存。
void SmartPointerDemo2()
{
// Create the object and pass it to a smart pointer
std::unique_ptr<LargeObject> pLarge(new LargeObject());
//Call a method on the object
pLarge->DoSomething();
// Free the memory before we exit function block.
pLarge.reset();
// Do some other work...
}
智能指针常常在设计模式中使用的比较多,如工厂模式、策略模式等。另外在大型程序中,对资源的频繁使用,也会使用到智能指针。具体到代码中,智能指针的使用场景主要是以下两点:
1、一个对象被多个指针指向的时候,使用shared_ptr ;
2、一个对象不需要被多个指针指向时,使用shared_ptr;