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

Posted

技术标签:

【中文标题】C++ 智能指针和指针到指针输出 API。模板化的“包装器”【英文标题】:C++ Smart Pointers and pointer-to-pointer output API's. Templated "wrapper" 【发布时间】:2015-02-05 14:56:09 【问题描述】:

在许多 API 尤其是 C 和 COM 类 API 中,工厂函数将创建对象并使用指向指针的指针将它们存储在调用者提供的位置。这与 std::unique_ptr、std::shared_ptr 和其他遵循相同样式的其他(例如,用于 COM 或其他侵入式引用计数方案)不直接兼容。

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**)(&amp;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);

【问题讨论】:

这里有问题吗? 这应该在 Code Review 上。 它看起来像示例代码(std::unique_ptr&lt;Foo&gt; myFoo; 等),如果您发布真实的工作代码,它将成为 Code Review 的主题。 (Foo**)(&amp;myUniquePtr) 绝对有味道。很糟糕。 std::unique_ptr&lt;Foo&gt; myFoo[] Foo* p; myApiFactory(33, &amp;p); return p; (); 有效,但相当可怕。 【参考方案1】:

这可以工作:

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

因为myFoo中存储的地址作为左值存储在p中。

【讨论】:

这个不需要参考吗?

以上是关于C++ 智能指针和指针到指针输出 API。模板化的“包装器”的主要内容,如果未能解决你的问题,请参考以下文章

指向数组的指针的 C++ 模板类动态数组

智能指针类模板

第61课 智能指针类模板

智能指针示例

c++三种智能指针以及相关知识自写智能指针

❥关于C++之智能指针