C++ 显式删除共享\u ptr
这里有一个简单的问题:是否允许您自己明确删除C++ 显式删除共享\u ptr,c++,boost,shared-ptr,boost-smart-ptr,C++,Boost,Shared Ptr,Boost Smart Ptr,这里有一个简单的问题:是否允许您自己明确删除boost::shared\u ptr?你应该这样做吗 澄清一下,我的意思不是删除共享\u ptr所持有的指针。我指的是实际的共享\u ptr本身。我知道大多数人建议不要这样做,所以我只是想知道显式地这样做是否可以。您不能强制其引用计数为零,否 想一想这需要什么才能起作用。您需要前往使用共享ptr的每个地方并清除它 如果您确实强制共享指针删除并将其设置为NULL,那么它就像一个弱的ptr。但是,代码中使用该共享\u ptr的所有位置都没有准备好,并且希
boost::shared\u ptr
?你应该这样做吗
澄清一下,我的意思不是删除
共享\u ptr
所持有的指针。我指的是实际的共享\u ptr
本身。我知道大多数人建议不要这样做,所以我只是想知道显式地这样做是否可以。您不能强制其引用计数为零,否
想一想这需要什么才能起作用。您需要前往使用共享ptr的每个地方并清除它
如果您确实强制共享指针删除并将其设置为NULL,那么它就像一个弱的ptr。但是,代码中使用该共享\u ptr的所有位置都没有准备好,并且希望保存一个有效指针。他们没有理由检查NULL,因此这些代码位将崩溃。你的问题不清楚。如果您已经动态分配了
共享\u ptr
,那么您当然可以随时删除它
但是,如果您询问是否允许删除由共享\u ptr
管理的任何对象,那么答案是。。。视情况而定。如果shared_ptr::unique
返回true,则调用shared_ptr::reset
将删除托管对象。但是,如果shared_ptr::unique
返回false,则表示有多个shared_ptr
s共享该对象的所有权。在这种情况下,调用reset
只会导致引用计数减少1,当管理该对象的最后一个共享\u ptr
超出范围或自身reset
时,将实际删除该对象
编辑:
编辑后,您似乎在询问删除动态分配的共享\u ptr
。大概是这样的:
auto sp = new boost::shared_ptr<int>( new int(42) );
// do something with sp
delete sp;
auto-sp=newboost::shared_ptr(newint(42));
//用sp做点什么
删除sp;
这是允许的,并将按预期工作,尽管这将是一个不寻常的用例。唯一需要注意的是,如果在sp
的分配和删除之间,您创建了另一个共享对象所有权的shared\u ptr
,则删除sp
不会导致删除对象,这只会在对象的引用计数变为0时发生。[编辑:你可以删除共享的
当且仅当它是用新建的
创建的,与任何其他类型相同。我不明白你为什么要用新建的
创建共享的
,但没有什么能阻止你。]
那么,您可以编写删除ptr.get();
这样做几乎不可避免地会导致未定义的行为,无论是当其他共享所有者使用其共享ptr
访问现在已删除的对象时,还是当对象的最后一个共享ptr
被销毁时,该对象再次被删除
所以不,你不应该
shared\u ptr
的目的是管理一个任何“个人”都无权或没有责任删除的对象,因为可能会有其他人共享所有权。因此,您也不应该希望这样做。如果您想模拟计数递减,可以在堆上手动执行,如下所示:
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;
}
但它并没有那么有用。在一些(非常?)罕见的情况下,明确删除很有用
除了显式删除之外,有时在“删除”共享指针时还必须显式销毁它
当与C代码交互时,事情会变得很奇怪,将共享的_ptr作为不透明值传递
例如,我有以下内容,用于向用C编写的Lua脚本语言传递对象和从中传递对象(www.Lua.org)
静态无效推送(lua_State*L,std::shared_ptr sp)
{
if(sp==nullptr){
卢阿努普什尼勒(L);
返回;
}
//这基本上是从C++的角度来看的。
void*ud=lua_newuserdata(L,sizeof(std::shared_ptr));
//复制构造函数,碰撞参考计数。
新(ud)标准::共享ptr(sp);
luaL_setmetatable(L,B::class_name);
}
因此,这是某个malloc'd内存中的共享\u ptr。相反的是…(在Lua垃圾收集对象并“释放”它之前调用设置)
static int destroy(lua_State*L)
{
//抓取不透明指针
void*ud=luaL\u checkudata(L,1,B::class\u name);
std::shared_ptr*sp=静态_cast(ud);
//显式调用,因为这是“新位置”
//递减ref计数
sp->~shared_ptr();
返回0;
}
当然可以删除(动态分配)共享\u ptr;删除它的内容是一个完全不同的问题;-)我认为你在寻找弱\u ptr
。动态分配共享\u ptr
违背了使用共享\u ptr
的目的。你到底为什么要在堆上分配共享\u ptr
?你的问题与“如果我用new分配一个对象,我可以显式地删除它吗?”……答案当然是肯定的——你可以而且应该这样做。对象的类型无关紧要。
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;
}
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 );
}
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;
}