这里有一个简单的问题:您是否允许自己显式删除 a boost::shared_ptr
?你应该吗?
澄清一下,我并不是说删除shared_ptr
. 我的意思是实际shared_ptr
本身。我知道大多数人建议不要这样做,所以我只是想知道是否可以明确地这样做。
这里有一个简单的问题:您是否允许自己显式删除 a boost::shared_ptr
?你应该吗?
澄清一下,我并不是说删除shared_ptr
. 我的意思是实际shared_ptr
本身。我知道大多数人建议不要这样做,所以我只是想知道是否可以明确地这样做。
你的问题不清楚。如果您已经shared_ptr
动态分配了 a ,那么您当然可以随时使用delete
它。
但是,如果您询问是否允许删除 由 管理的任何对象shared_ptr
,那么答案是……这取决于。如果shared_ptr::unique
返回 true,则调用shared_ptr::reset
将删除托管对象。但是,如果shared_ptr::unique
返回 false,则表示该对象有多个shared_ptr
共享所有权。在这种情况下,调用reset
只会导致引用计数减 1,当最后一个shared_ptr
管理该对象超出范围或者是它本身时,将发生对象的实际删除reset
。
编辑:
编辑后,您似乎在询问是否要删除动态分配的shared_ptr
. 像这样的东西:
auto sp = new boost::shared_ptr<int>( new int(42) );
// do something with sp
delete sp;
这是允许的,并且会按预期工作,尽管这将是一个不寻常的用例。唯一需要注意的是,如果在分配和删除之间sp
创建另一个shared_ptr
共享对象所有权的对象,则删除sp
不会导致对象被删除,这只会在对象的引用计数变为 0 时发生。
[编辑:delete
当shared_ptr
且仅当它是用new
, 与任何其他类型一样创建时,您可以。我想不出你为什么要创建一个shared_ptr
with new
,但没有什么能阻止你。]
嗯,你可以写delete ptr.get();
。
这样做几乎不可避免地会导致未定义的行为,或者当其他共享所有者使用他们shared_ptr
访问现在已删除的对象时,或者该shared_ptr
对象的最后一个被销毁,并且该对象再次被删除。
所以不,你不应该。
的目的shared_ptr
是管理一个没有任何“人”有权或有责任删除的对象,因为可能有其他人共享所有权。所以你也不应该想要。
您不能将其引用计数强制为零,不。
想想它需要什么才能起作用。您需要去每个使用 shared_ptr 的地方并清除它。
如果您确实强制删除共享指针并将其设置为 NULL,那么它就像一个weak_ptr。但是,代码中使用 shared_ptr 的所有这些地方都没有为此做好准备,并且期望持有一个有效的指针。他们没有理由检查 NULL,因此这些代码会崩溃。
如果要模拟计数递减,可以在堆上手动执行,如下所示:
int main(void) {
std::shared_ptr<std::string>* sp = new std::shared_ptr<std::string>(std::make_shared<std::string>(std::string("test")));
std::shared_ptr<std::string>* sp2 = new std::shared_ptr<std::string>(*sp);
delete sp;
std::cout << *(*sp2) << std::endl; // test
return 0;
}
或者在堆栈上使用std::shared_ptr::reset()
如下:
int main(void) {
std::shared_ptr<std::string> p = std::make_shared<std::string>(std::string("test"));
std::shared_ptr<std::string> p2 = p;
p.reset();
std::cout << *p2 << std::endl; // test
return 0;
}
但它不是那么有用。
Expliticly deleting comes in handy in some (very?) rare cases.
In addition to explicitly deleting, sometimes you HAVE to explicitly destruct a shared pointer when you are 'deleting' it!
Things can get weird when interfacing with C code, passing a shared_ptr as an opaque value.
For example I have the following for passing objects to and from the Lua scripting language which is written in C. (www.lua.org)
static void push( lua_State *L, std::shared_ptr<T> sp )
{
if( sp == nullptr ) {
lua_pushnil( L );
return;
}
// This is basically malloc from C++ point of view.
void *ud = lua_newuserdata( L, sizeof(std::shared_ptr<T>));
// Copy constructor, bumps ref count.
new(ud) std::shared_ptr<T>( sp );
luaL_setmetatable( L, B::class_name );
}
So thats a shared_ptr in some malloc'd memory. The reverse is this... (setup to be called just before Lua garbage collects an object and 'free's it).
static int destroy( lua_State *L )
{
// Grab opaque pointer
void* ud = luaL_checkudata( L, 1, B::class_name );
std::shared_ptr<T> *sp = static_cast<std::shared_ptr<T>*>(ud);
// Explicitly called, as this was 'placement new'd
// Decrements the ref count
sp->~shared_ptr();
return 0;
}