3

如何将智能 ptr 传递给以指针为参数的函数?

smart_ptr<T> val; // I have this smart pointer

// And I want to pass it to this function, so that this function will fill the smart pointer with proper value
void Foo(T*& sth)
{
    sth = memoryAddress;
}

编辑现在我明白了。谢谢大家的答案!

4

3 回答 3

7

简单的答案是你不能。虽然智能指针几乎可以肯定在内部包含T*某个地方,但智能指针强制执行各种不变量,如果您可以在不通过用户界面的情况下更改此指针,其中许多可能会被破坏。唯一的解决方案是使用原始指针调用函数,然后使用原始指针初始化智能指针,前提是您确定您获得的指针符合智能指针的要求(例如由new操作员分配) .

于 2013-07-23T14:21:07.143 回答
4

呃,这个 API 很丑。

我将假设该函数承诺它“返回”的指针拥有一个资源,该资源将被调用者以这种方式删除smart_ptr,并且smart_ptr可以从任意指针初始化。否则不能这样做。

您可以像在没有智能指针的情况下一样抓住指针,然后将其放入智能指针中。

T* ptr;
Foo(ptr);
smart_ptr<T> val(ptr);

可能的情况是智能指针已经拥有某些东西,而您想将该东西传递给函数,然后替换智能指针拥有的东西。那……更难看。

我不知道该函数是否会获得您传入的资源的所有权(通常,我希望不会,但由于 API 如此丑陋,我不会发誓)。这导致了两种不同的情况。

如果函数取得您传递的资源的所有权,即它关心删除指针本身,则智能指针类型必须是可以放弃资源所有权的类型,就像std::unique_ptr成员release()函数一样。值得注意的是,std::shared_ptr不能这样做(考虑到其他shared_ptrs 也可能拥有它)。

因此,假设智能指针具有该功能,并且能够重新初始化为任意指针(例如 with std::unique_ptr::reset),您可以执行以下操作:

//smart_ptr<T> val;
T* ptr = val.release();
Foo(ptr);
val.reset(ptr);

如果函数不获取资源的所有权,则所需要的只是使用任意指针重新初始化的能力。

//smart_ptr<T> val;
T* ptr = val.get();
Foo(ptr);
val.reset(ptr);
于 2013-07-23T14:18:05.397 回答
1

你不能那样做。T* raw = val.get()您可以使用 " " then " "传递原始指针,Foo(raw)但不能shared_ptr在内部设置 a 的原始指针Foo。如果要Foo设置shared_ptr,请使其采用非常量shared_ptr引用。

像这样:

template<typename T>
Foo(shared_ptr<T>& ptr)
{
    ptr.reset(memoryAddress); // Or assign it, or make_shared, or whatever.
}

shared_ptr<int> intptr;
Foo(intptr);

或者更好的是,Foo返回 ashared_ptr而不是通过引用获取它。

于 2013-07-23T14:14:54.953 回答