显式删除shared_ptr
Explicitly deleting a shared_ptr
这里有一个简单的问题:是否允许您自己显式删除boost::shared_ptr
?你应该吗?
澄清一下,我的意思不是删除shared_ptr
持有的指针。我指的是真正的shared_ptr
本身。我知道大多数人建议不要这样做,所以我只是想知道明确地这样做是否可以。
您的问题不清楚。如果你已经动态地分配了一个shared_ptr
,那么你当然可以随时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时才会发生这种情况。
[编辑:如果并且仅当它是用new
创建的,则可以用delete
创建shared_ptr
,与任何其他类型一样。我想不出为什么要用new
创建shared_ptr
,但没有什么能阻止你。]
嗯,您可以编写delete ptr.get();
。
这样做几乎不可避免地会导致未定义的行为,无论是当其他共享所有者使用他们的shared_ptr
访问现在已删除的对象时,还是当该对象的最后一个shared_ptr
被销毁,并且该对象再次被删除时。
所以不,你不应该。
shared_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;
}
或者在使用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;
}
但它并没有那么有用。
您不能强制其引用计数为零
想想这需要什么才能奏效。你需要去每个使用shared_ptr的地方并清除它
如果您确实强制删除共享指针并将其设置为NULL,那么它就像一个weak_ptr。然而,代码中使用shared_ptr的所有位置都没有准备好,并且期望持有有效的指针。他们没有理由检查NULL,所以这些代码会崩溃。
在某些(非常?)罕见的情况下,显式删除会派上用场。
除了显式删除外,有时在"删除"共享指针时,还必须显式销毁它!
当与C代码接口时,将shared_ptr作为不透明值传递时,事情可能会变得奇怪。
例如,我有以下内容来向Lua脚本语言传递对象,该语言是用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 );
}
所以这是某个malloc内存中的一个shared_ptr。相反的是。。。(在Lua垃圾收集对象并释放它之前调用设置)。
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;
}
- CLANG 编译器 说:变量"PTR"可能未初始化
- 在以唯一ptr为值的C++映射中,动态内存何时会被销毁
- 将 ptr 传递给 ptr 到 A 作为参数传递给 A 的函数是不好的做法吗?
- 为共享 ptr 向量实现复制 c'tor?
- 字符和整数中 **(ptr+1) 的值差异
- C++:在不中断共享的情况下通过引用传递共享 PTR?
- 如何将派生类从基 ptr 分配给 nlohmann::json
- 引用 std::shared:ptr 以避免引用计数
- 为什么我不能在不进行任何转换的情况下将浮点数放入任何类型的 ptr 中?
- 在调用函数时,ptr** 和 ptr*& 之间是否有区别,或者首选C++?
- 另一种类型的智能ptr,比如具有弱refs的unique_ptr
- 尝试打印出 *ptr++ 的值,以了解它是如何工作的
- 如何控制共享 ptr 引用计数?
- dopen():不以 root 身份运行时"failed to map segment from shared object"
- C++中的指针否定 (!ptr == NULL)
- 从const ptr*转换为ptr*时出现问题
- 无法使用 libtool 将 -shared 参数传递给 g++
- boost::shared_ptr和std::shared-ptr的同居
- 我可以用std::shared_ptr而不是boost::shared-ptr构建boost库吗
- shared-ptr-C++shared_ptr与unique_ptr用于资源管理