Anw*_*sha 5 c++ shared-ptr unique-ptr
我们都知道我们可以在C++中轻松地将unique_ptr转换为shared_ptr.但是,如果我做了这样的转换怎么办:
unique_ptr<X> u=make_unique<X>(); // X is some class
shared_ptr<X> s=move(u); // this works of course
Run Code Online (Sandbox Code Playgroud)
现在我想将指针的所有权转移s回去u.可悲的是,除此之外release() function in shared_ptr like in unique_ptr别无他法: -
u.reset(s.release());
Run Code Online (Sandbox Code Playgroud)
此外,这也无法奏效: -
u.reset(s.get());
Run Code Online (Sandbox Code Playgroud)
任何人都可以建议我如何转换shared_ptr到unique_ptr或至少释放所拥有的指针shared_ptr?
Fil*_*efp 12
标准库并没有真正促进这一举措,从去std::unique_ptr到std::shared_ptr永远是安全的(因为这两个语义的) -但相反的是危险的,因为有可能是资源不是特定的更多的业主std::shared_ptr,你想从移动.
我可能会再告诉你一次,但我会假设你有点长大,可以对你自己的决定负责.
如果你想破解一个不会是未定义的解决方案- 行为,除非std::unique_ptr超出范围并且你仍然有std::shared_ptrs直接或间接最终使用资源...你可能最终得到类似的东西:
#include <memory>
Run Code Online (Sandbox Code Playgroud)
namespace hack {
struct conditional_deleter {
void disable () { _do_delete = false; }
template<class T>
void operator()(T* p) {
if (_do_delete)
delete p;
}
bool _do_delete = true;
};
}
Run Code Online (Sandbox Code Playgroud)
int main () {
std::unique_ptr<int> up (new int (123));
std::shared_ptr<int> sp (up.release (), hack::conditional_deleter {});
std::shared_ptr<int> sb (sp);
std::get_deleter<hack::conditional_deleter> (sp)->disable ();
std::unique_ptr<int> ub (sp.get ()); // see the name of this variable?
} // can I get a ticket to UB-land, please?
Run Code Online (Sandbox Code Playgroud)
警告
上面的内容远非推荐的实践,如果你发现自己处于需要这样的事情的情况下你应该放火烧你的工作站 - 可能你的整个房子 - 并开始一个新的程序设计.
正如每个人都提到的,您无法转换shared_ptr为unique_ptr,因为可能有多个人shared_ptr拥有该对象。因此没有release() functionfor shared_ptr。如果有一个 & 你会release()在一个shared_ptr对象上使用,当多个这样的对象共享资源时,那么其他shared_ptr指针对于它们是否拥有该资源就会产生歧义。
但是,因为您的实际问题是关于 of static& dynamic casting(unique_ptr正如您在评论中提到的),所以我想补充一点,您实际上不需要使用shared_ptrfor casting unique_ptr& ,在这里我向您展示如何非常简单地做到这一点:-
void dynamic_unique_cast (unique_ptr<Parent> &pa)
{
unique_ptr<Child> pb;
Parent *p=pa.release(); // release ownership
try
{
pb.reset(dynamic_cast<Child*>(p)); // perform casting
if (pb==nullptr)
throw runtime_error {"nullptr exception"};
cout<<"dynamic_cast successful\n\n";
pa.reset(pb.release()); // if casting is successful then `pb` returns ownership back to `pa`
}
catch (exception &e)
{
cout<<"dynamic_cast unsuccessful: "<<e.what()<<"\n\n";
pa.reset(p); // if casting fails then `p` returns ownership to `pa`
}
}
void static_unique_cast (unique_ptr<Parent> &pa)
{
unique_ptr<Child> pb;
Parent *p=pa.release();
try
{
pb.reset(static_cast<Child*>(p));
if (pb==nullptr)
throw runtime_error {"nullptr exception"};
show(pb);
cout<<"static_cast successful\n\n";
pa.reset(pb.release());
}
catch (exception &e)
{
cout<<"static_cast unsuccessful: "<<e.what()<<"\n\n";
pa.reset(p);
}
}
Run Code Online (Sandbox Code Playgroud)
上面的代码运行得很好并且肯定会解决你的问题。如果您有任何歧义,请随时发表评论。