C++智能指针和指针指针输出API。模板化的“包装器”

问题描述:

在许多API中,特别是类似于C和COM的API,工厂函数将创建对象并使用指向指针的指针将它们存储在调用者提供的位置。这与std :: unique_ptr,std :: shared_ptr和其他遵循相同样式(例如,用于COM或其他侵入式引用计数方案)的其他程序不是直接兼容的。C++智能指针和指针指针输出API。模板化的“包装器”

void myApiFactory(int x, Foo **out); 

std::unique_ptr<Foo> myFoo; 
myApiFactory(33, &myFoo);//not possible 

//works, but bit of a pain, especially with API's that have lots of such things 
Foo *tmp = nullptr; 
myApiFactory(33, &tmp); 
myFoo.reset(tmp); 

//What I'm looking for 
myApiFactory(33, outPtr(myFoo)); 

实现我想到的是,这似乎编译,但我不知道它是正确的和安全的(例如像我明白(Foo**)(&myUniquePtr)是不是安全的,但编译和对我的作品)?

/**@brief Type created and returned by outPtr(T &smartPtr)*/ 
template<class T> 
class OutPtr 
{ 
public: 
    typedef typename T::pointer pointer; 
    /**Constructor for outPtr*/ 
    explicit OutPtr(T &smartPtr) 
     : smartPtr(&smartPtr) 
     , ptr(NULL) 
    {} 
    /**Move constructor for outPtr return*/ 
    OutPtr(OutPtr<T> &&mv) 
     : smartPtr(mv.smartPtr) 
     , ptr(mv.ptr) 
    { 
     mv.smartPtr = NULL; 
     mv.ptr = NULL; 
    } 

    /**Destructor that stores the pointer set to the pointer to pointer in the 
    * provided smart pointer. 
    */ 
    ~OutPtr() 
    { 
     if (smartPtr) 
      smartPtr->reset(ptr); 
    } 

    /**Implicit conversion to give the pointer to pointer to the function being 
    * called. 
    */ 
    operator pointer*() 
    { 
     assert(ptr == NULL); 
     return &ptr; 
    } 
private: 
    T* smartPtr; 
    pointer ptr; 
    //Should not be used, cause a compile error 
    OutPtr(const OutPtr&); 
    OutPtr& operator = (const OutPtr&); 
    OutPtr& operator = (OutPtr&&); 
}; 


/**Provides a safe means to store an output pointer directly into an 
* std::unique_ptr or similar smart pointer. The only requirement 
* is that there is a pointer typedef, and a reset method that accepts a 
* pointer of that type. 
* 
* void someFunction(int a, int b, Foo **out); 
* 
* std::unique_ptr<Foo,MyDeleter> foo; 
* someFunction(4, 23, outPtr(foo)); 
*/ 
template<class T> 
OutPtr<T> outPtr(T &ptr) 
{ 
    return OutPtr<T>(ptr); 
} 
+1

这里有问题吗? – 2015-02-05 15:09:33

+2

这应该是代码审查。 – 2015-02-05 15:16:53

+1

它看起来像示例代码('std :: unique_ptr myFoo;'等等),如果您发布了真实的工作代码,那么它就是Code Review的主题。 – Phrancis 2015-02-05 15:20:18

这可以工作:

auto p = myFoo.get(); 
myApiFactory(33, &p); 

由于存储在myFoo的地址被存储在p作为L值。

+0

不需要参考吗? – Quentin 2015-02-05 15:38:46