如何将 reset 与指向非 const 对象的 const 共享指针一起使用?

how to use reset with const shared pointer to non const object?

我正在尝试重置共享指针,它是来自具有常量结构的容器迭代器的结构成员"elements"。
代码无法编译,出现错误:

cannot convert 'this' pointer from 'const boost::shared_ptr<boost::log::v2s_mt_nt6::sinks::text_file_backend>' to 'boost::shared_ptr<boost::log::v2s_mt_nt6::sinks::text_file_backend> &'

这个错误告诉我 const 共享指针不允许被重置使用??!!这是真的吗?
如果是这样,我如何将这个 const 共享指针转换为非 const 以供重置使用??

如果您有 const shared_ptr<T>,则您无法更改它指向的内容。这就是 const 的本质。因此,您不能调用 reset,因为那样会改变它指向的内容。

您可以创建一个非 const 副本,并更改​​它指向的内容,但这仍然不会更改原始 const 指针。

不要尝试做任何可能删除 const shared_ptr<T> 持有的指针的事情,比如在其上调用 reset()

如果你做类似 delete myConstSharedPtr.get(); 的事情,当引用计数将达到 0 时,delete 将在存储的指针上再次调用,基本上会导致双重释放错误。

此外,您应该重新考虑您的设计并决定 shared_ptr 是否真的是您想在这里使用的。


最后,作为最后的手段,如果这个 shared_ptr 的常量来自外部库,它不应该强加这个 const 限制并且你不能正确修补它,那么 const_cast就是为这种情况而生的。但是算了,你真的不想用那个。

还在吗?以下是如何使用 const_cast 强制重置 const shared_ptr.

template<typename T>
void forceReset(const std::shared_ptr<T> ptr){
   const_cast<std::shared_ptr<T>&>(ptr).reset();
}

警告:如果这段代码乍一看符合您的要求,则意味着您所依赖的错误库泄漏了内存。确实没有办法detach一个shared_ptr,也就是在不更新引用计数的情况下销毁它。这意味着除非引用强制删除资源的共享指针之一是动态分配的,并且在程序结束之前永远不会被删除,否则将发生双重释放,导致未定义的行为……可能是严重的崩溃。

但是如果你仍然想继续,你绝对不应该,你可以利用它来防止引用计数器达到零,代价是一个小的内存泄漏,它将在程序退出时被清理.内存泄漏不会导致任何类型的未定义行为。

template<typename T>
void forceReset(const std::shared_ptr<T> ptr){
   //This leaked shared_ptr will prevent automatic deletion
   new std::shared_ptr<T>(ptr);
   const_cast<std::shared_ptr<T>&>(ptr).reset();
}

另一个免责声明:我强烈反对任何人使用此 hack。我给它是为了讨论乱用智能指针和const_cast的风险。请再考虑一次修补有问题的库或使用另一个库。