Nik*_*iou 6 c++ stl smart-pointers c++11 c++14
问题产生于对条件接口的需求.可能是因为我陷入了XY问题,但是(底线)我最终需要一个共享指针(基于运行时选择)管理或不管理(拥有或不拥有)资源.
以下是对非拥有共享指针的一些想法
使用placement new,例如:
struct MyStruct {};
MyStruct ms1;
std::shared_ptr<MyStruct> sp(new(&ms1) MyStruct);
Run Code Online (Sandbox Code Playgroud)使用虚拟删除器
std::shared_ptr<MyStruct> spn(new MyStruct, [](MyStruct*){});
Run Code Online (Sandbox Code Playgroud)我的类布局(将使用非拥有共享指针)如下所示:
template<typename T>
struct blah
{
shared_ptr<T> _m;
};
Run Code Online (Sandbox Code Playgroud)
现在,该_m成员可能拥有或可能不拥有基于运行时选择的资源.我没有使用的原因weak_ptr是因为_m实际上可能是一个拥有指针.
T.C*_*.C. 11
placement new显然是UB,因为它会在你的代码片段中尝试删除堆栈上的东西.空删除器版本将起作用,但将分配引用计数块.
诀窍是使用疯狂(ok,aliasing)构造函数shared_ptr:
template< class Y >
shared_ptr( const shared_ptr<Y>& r, T *ptr );
Run Code Online (Sandbox Code Playgroud)
构建一个shared_ptr拥有什么r,但指向什么ptr指向,即:
std::shared_ptr<MyStruct> sp(std::shared_ptr<MyStruct>(), p);
Run Code Online (Sandbox Code Playgroud)
这是noexcept由标准保证的,不会分配任何东西.该标准甚至还有一个说明
[ 注意:此构造函数允许
shared_ptr使用非null存储指针创建空实例.- 结束说明 ]
该展示位置new将在销毁时为您提供未定义的行为(可能是崩溃) - 它会立即调用delete未创建的内容new.
我会选择无操作删除器.设计可能看起来很奇怪,但如果你需要这样的行为(并且记录得足够多),它就会起作用.我在我的一个项目中使用了类似的东西一段时间,但后来我摆脱了它的需要.