将取消引用的智能指针的地址传递给需要原始指针的函数
Passing the address of dereferenced smart pointers to functions that expect raw pointers
(假设我正在使用需要使用原始指针的库或框架,)
使用拥有一些数据的智能指针,然后将取消引用的智能指针的地址传递给需要原始指针的函数是否有效?
只要函数不期望获得数据的所有权,就可以。
事实上,这也是您应该如何设计自己的函数:当且仅当它应该参与指针对象的所有权时,才在接口中使用智能指针。
是的,这是有效的做法。 std
智能指针有一个 get()
成员函数正是为此目的。
一般来说,当你通过智能指针管理一个对象时,当这些函数暗示所有权语义时,你应该只将整个智能指针对象按原样传递给其他函数:如果一个函数将复制一个std::shared_ptr
,它应该按值接受它。 std::unique_ptr
类似。更常见的是,一个函数与所有权没有任何关系,它只是想对传递给它的数据 and/or 行为进行操作。然后,您的第一选择应该是采用(const
-限定的)引用,因为它没有额外的nullptr
-状态的指针。否则,一个指针就好了。
长话短说:如果你处理一个 API 接受原始指针并且不对其执行任何与所有权相关的操作(删除它,复制指针),那么传递 .get()
到它。
Is it valid practice to use a smart pointer which owns some data, and then pass the address of the derefenced smart pointer to a function that expects a raw pointer?
是的,这可能是一种有效的做法...只要该函数不拥有该原始指针。但是,重要的是要注意传递的指针将使用多长时间。智能指针的生命周期必须匹配或超过该指针的使用。
如果函数确实获得所有权,那么从智能指针传递地址 release
d 可能是一种有效的做法,但前提是删除器与框架将对指针执行的操作相匹配.
上面的回答是正确的,我只想补充一个小问题:关于线程执行的时候。那么你应该格外小心那些采用原始指针的函数,因为这些函数在执行时可能会变得无效并且其他堆栈已经释放了它们。
在设计自己的线程函数时,最好使用 std::shared_ptr
,即使该函数可以使用原始指针。
struct foo = {...};
void testfoo(foo* msg)
{
}
if (1)
{
shared<foo> f = std::make_shared<foo>(...);
std::thread t(testfoo,f.get());
t.detach();
} // whops. f destructed perhaps before testfoo could manipulate it
更好:
void testfoo(std::shared_ptr<foo> msg)
{
}
if (1)
{
shared<foo> f = std::make_shared<foo>(...);
std::thread t(testfoo,f);
t.detach();
} // f has been copied, so no pointer release
(假设我正在使用需要使用原始指针的库或框架,)
使用拥有一些数据的智能指针,然后将取消引用的智能指针的地址传递给需要原始指针的函数是否有效?
只要函数不期望获得数据的所有权,就可以。
事实上,这也是您应该如何设计自己的函数:当且仅当它应该参与指针对象的所有权时,才在接口中使用智能指针。
是的,这是有效的做法。 std
智能指针有一个 get()
成员函数正是为此目的。
一般来说,当你通过智能指针管理一个对象时,当这些函数暗示所有权语义时,你应该只将整个智能指针对象按原样传递给其他函数:如果一个函数将复制一个std::shared_ptr
,它应该按值接受它。 std::unique_ptr
类似。更常见的是,一个函数与所有权没有任何关系,它只是想对传递给它的数据 and/or 行为进行操作。然后,您的第一选择应该是采用(const
-限定的)引用,因为它没有额外的nullptr
-状态的指针。否则,一个指针就好了。
长话短说:如果你处理一个 API 接受原始指针并且不对其执行任何与所有权相关的操作(删除它,复制指针),那么传递 .get()
到它。
Is it valid practice to use a smart pointer which owns some data, and then pass the address of the derefenced smart pointer to a function that expects a raw pointer?
是的,这可能是一种有效的做法...只要该函数不拥有该原始指针。但是,重要的是要注意传递的指针将使用多长时间。智能指针的生命周期必须匹配或超过该指针的使用。
如果函数确实获得所有权,那么从智能指针传递地址 release
d 可能是一种有效的做法,但前提是删除器与框架将对指针执行的操作相匹配.
上面的回答是正确的,我只想补充一个小问题:关于线程执行的时候。那么你应该格外小心那些采用原始指针的函数,因为这些函数在执行时可能会变得无效并且其他堆栈已经释放了它们。
在设计自己的线程函数时,最好使用 std::shared_ptr
,即使该函数可以使用原始指针。
struct foo = {...};
void testfoo(foo* msg)
{
}
if (1)
{
shared<foo> f = std::make_shared<foo>(...);
std::thread t(testfoo,f.get());
t.detach();
} // whops. f destructed perhaps before testfoo could manipulate it
更好:
void testfoo(std::shared_ptr<foo> msg)
{
}
if (1)
{
shared<foo> f = std::make_shared<foo>(...);
std::thread t(testfoo,f);
t.detach();
} // f has been copied, so no pointer release