C++11 unique_ptr           

C++11 unique_ptr

modern effective c++ 中的例子

假设我们有 Base class: Investment, 及其子类 Stock(股票), Bond(债券), RealEstate(房地产)  
class Investment { … };

class Stock : public Investment { ... };

class Bond : public Investment { ... };

class RealEstate : public Investment { ... };

工厂函数通常从堆上分配一个对象,然后返回一个指向它的指针,当不再需要它的时候,调用者要负责delete这个对象。那真是完美匹配std::unique_ptr,因为调用者需要为工厂返回的资源负责(即独占资源的所有权),然后std::unique_ptr在它销毁的时候可以自动 delete 它指向的对象。  

 {                  
   ...
   auto pInvestment =                       // pInvestment的类型是
         makeInvestment(*arguments*);       // std::unique_ptr<Investment>
   ...
 }    // 销毁 *pInvestment

deleter 可以是函数对象,也可以是 lambda

auto delInvmt = [](Investment *pInvestment)   // 自定义的删除器
            {                                 // 一个lambda表达式
                makeLogEntry(pInvestment); 
                delete pInvestment;
            };

template <typename... Ts>
std::unique_ptr<Investment, decltype(delInvmt)>   // 修改返回类型
makeInvestment(Ts&&... params)
{`
    std::unique_ptr<Investment, decltypedelInvmt)>
       pInv(nullptr, delInvmt);                   // 将要返回的指针
    if ( /* a Stock object should be created */ )
    {
        pInv.reset(new Stock(std::forward<Ts>(params)...));
    }
    else if (/* a Bond object should be created */) 
    {
        pInv.reset(new Bond(std::forward<Ts>(params)...));
    }
    else if ( /* a RealEstate obejct should be created */ )
    {
        pInv.reset(new RealEstate(std::forward<Ts>(params)...));
    }

    return pInv;
}      对程序的几点说明:

   单独的对象形式(std::unique_ptr), 该形式没有下标引用操作(operator[])     数组形式(std::unique_ptr<T[]>), 改形式没有解引用操作(operator*和operator->)    

这是为什么std::unique_ptr如此适合做工厂函数的关键原因,工厂函数不会知道:独占所有权语义和共享所有权语义哪个更适合调用者。通过返回一个std::unique_ptr,工厂提供给调用者的是最高效的智能指针,但它不妨碍调用者用std::shared_ptr来替换它

to be remembered

unique_ptr 用来实现 Pimpl Idiom

参见 effective modernc C++ item 22