问题
(assuming that I am working with a library or framework that expects usage of raw pointers,)
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?
回答1:
Yes, that is valid practice. The std
smart pointers have a get()
member function exactly for that purpose.
In general, when you manage an object through smart pointers, you should only pass the whole smart-pointer-object as is to other functions when these functions imply ownership semantics: if a function will copy a std::shared_ptr
, it should accept it by value. Similar for std::unique_ptr
. More often than that, a function doesn't have anything to do with ownership, it just wants to act on data and/or behavior passed into it. Then, your first choice should be to take a (const
-qualified) reference, because it doesn't have the additional nullptr
-state of pointers. Otherwise, a pointer is just fine.
Long story short: if you deal with an API that accepts raw pointers and doesn't do any ownership-related actions on it (delete it, copy the pointee), then it's fine to pass .get()
to it.
回答2:
As long as the function doesn't expect to take ownership of the data, definitely.
In fact, that is also how you should design your own functions: use a smart pointer in an interface if, and only if, it should participate in the ownership of the pointee.
回答3:
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?
Yes, that is potentially a valid practice... as long as that function doesn't take ownership of that raw pointer. However, it is important to take note how long the passed pointer will be used. The lifetime of the smart pointer must match or exceed the use of that pointer.
In case the function does take ownership, then it may instead be a valid practice to pass an address release
d from the smart pointer, but only if the deleter matches what the framework would do with the pointer.
回答4:
The above answers are correct, I 'd only want to add a minor catch: When it's about threaded execution. Then you should be extra-careful about functions that take raw pointers because these may become invalid while executing and the other stack has released them.
When designing your own functions that will go threaded, it might be better to use std::shared_ptr
even if the function could use a raw pointer.
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
Better:
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
来源:https://stackoverflow.com/questions/64873544/passing-the-address-of-dereferenced-smart-pointers-to-functions-that-expect-raw