将std :: unique_ptr作为参数传递给函数

时间:2011-09-09 15:19:06

标签: c++ function parameters compiler-errors unique-ptr

我得到了一个结构和功能如下:

struct MYOVERLAPPED : public OVERLAPPED
{
    //...
};


void func1(std::unique_ptr<MYOVERLAPPED> pBuf)
{
    //...
};

我正在获取一个指向MYOVERLAPPED的指针,我希望将其传递给func1函数。 我遇到的问题是,无论我尝试什么,我都会遇到以下错误:

我已经尝试过以下内容: Try1:

std::unique_ptr<OVERLAPPED> pOver(//....)
HandleAcceptIndication(std::move(pOver));
  

错误:错误1错误C2440:'初始化':无法转换   '_OVERLAPPED **'到'MYOVERLAPPED *'

Try2:

HandleAcceptIndication(new ACCEPT_OVERLAPPED);
  

错误1错误C2664:'HandleAcceptIndication':无法转换   参数1从'MYOVERLAPPED *'到'std :: unique_ptr&lt; _Ty&gt;'

任何人都知道如何将这个OVERLAPPED的指针指针传递给MYOVERLAPPED函数以及为什么Try2不起作用,因为我随便使用std::unique_ptr<MYOVERLAPPED> pO(new MYOVERLAPPED)哪个有效...?

3 个答案:

答案 0 :(得分:11)

虽然您无法直接从std::unique_ptr<base>转换为std::unique_ptr<derived>,但编写安全的强制转换功能并不太难(即不会泄漏任何资源)情况,只有在演员表有效时才会成功:

template <typename Dst, typename Src>
std::unique_ptr<Dst> unique_dynamic_cast( std::unique_ptr<Src>& ptr ) {
    Src * p = ptr.release();                             // [1]
    std::unique_ptr<Dst> r( dynamic_cast<Dst*>(p) );     // [2]
    if ( !r ) {
        ptr.reset( p );                                  // [3]
    }
    return r;                                            // [4]
}

基本思想是我们需要从std::unique_ptr中提取指针并在[1]中将其放在一边。我们无法直接尝试dynamic_cast,如果失败,ptr将释放所有权,内存将被泄露。然后我们尝试从指向所请求的指针类型的本地指针执行dynamic_cast [2],并将所有权传递给r结果唯一指针。如果dynamic_cast失败,那么r将为空,我们需要将内存的所有权返回到原始std::unique_ptr [3],以便调用代码来决定如何处理它。然后我们将[em>转换的 std::unique_ptr返回给[4]中的调用者。

答案 1 :(得分:2)

这不起作用,因为您试图在继承层次结构中强制转换。您正试图隐式地将Base *转换为Derived *。

答案 2 :(得分:0)

unique_ptr<A>unique_ptr<B>是不相关的类型。除非在A*B*之间存在隐式转换(感谢UncleBens),否则您无法在它们之间进行转换,在这种情况下不是这样。此外,您不应该使用不是要转换为的子类的实例来强制转换继承层次结构。在这种情况下,您尝试将OVERLAPPED投射到MYOVERLAPPED这是一个无效的演员,因为OVERLAPPED不是MYOVERLAPPED。这就是为什么你不能在unique_ptr类型之间进行转换。

如果您只是想将unique_ptr传递给func1,可以这样做:

func1(shared_ptr<MYOVERLAPPED>(new MYOVERLAPPED));

此外,通过将unique_ptr传递给函数,原始指针中的指针将设置为NULL。如果您没有将shared_ptr作为临时文件创建并将其传递给函数,并且稍后需要使用相同的实例,请考虑使用引用或unique_ptr