Can I not have common pointers?

Introduction

The question arose because of the need for a conditional interface. It may be that I got into the XY problem, but (on the bottom line) I had to use a common pointer, which (based on the choice of runtime) would control whether or not (own or not) the resource.

While we work

Below are some thoughts on not owning a shared pointer

  • Using a new placement, for example:

    struct MyStruct {}; MyStruct ms1; std::shared_ptr<MyStruct> sp(new(&ms1) MyStruct); 
  • Using bogus delete

     std::shared_ptr<MyStruct> spn(new MyStruct, [](MyStruct*){}); 

Question

  • Is there a standard way?
  • Is there a β€œdon't do this” rule?
  • Is there at least a better way?

Notes

My class layout (where a generic pointer not belonging to it will be used) looks like this:

 template<typename T> struct blah { shared_ptr<T> _m; }; 

Now the _m member may or may not have a resource based on the choice of runtime. The reason I am not using weak_ptr is because _m can actually be the owner pointer.

+6
source share
2 answers

Placing the new one is obviously UB, as it will try to remove your fragment on the stack. An empty deletion version will work, but a link counting block will be highlighted.

The trick is to use the crazy (ok, aliasing) shared_ptr constructor:

 template< class Y > shared_ptr( const shared_ptr<Y>& r, T *ptr ); 

which builds a shared_ptr , owning what r has, but indicating what ptr pointing to, ptr .:

 std::shared_ptr<MyStruct> sp(std::shared_ptr<MyStruct>(), p); 

It is guaranteed noexcept by standard and does not stand out. There is even a note in the standard that says

[Note. This constructor allows you to create an empty shared_ptr instance with a non-zero stored pointer. -end note]

+11
source

Placing new will give you undefined behavior (and most likely a failure) upon destruction - it will promptly call delete on what was not created using new .

I would go with a no-op deleter. The design may seem strange, but if you need this behavior (and just document it enough), it will work. I used something like this in one of my projects for a while, but then I got rid of the need.

+7
source

Source: https://habr.com/ru/post/976296/


All Articles