Storing the raw pointer returned from the method in a smart pointer

Scenario:
I use a method from the old C ++ library that returns a raw pointer to SomeClass , where SomeClass is an exported class from the library header, for example SomeClass.h

The following is the LibraryMethod signature I am using:

 SomeClass* LibraryMethod(); 

I do not have access to modify the library. I use only binary and public header, which is a typical scenario.

I do not want to use raw pointers in my piece of code. Therefore, I have a generic pointer to SomeClass in my part of the code using the library API.

 std::shared_ptr<SomeClass> some_class; 

which I initialize to avoid storing a raw pointer to SomeClass

 some_class = (std::shared_ptr<SomeClass>)LibraryMethod(); 

It basically works, but I want to understand the details here.

Question:
Is the above correct technique?
Am I leaking here?
Are there more efficient methods for handling such a scenario?

+5
source share
4 answers

You really have to call him

 auto some_class = std::shared_ptr<SomeClass>(LibraryMethod()); 

This assumes that LibraryMethod allocates a pointer and passes you the memory property.

As currently written, you are trying to pass a raw pointer to std::shared_ptr using a C-style cast (which can lead to reinterpret_cast ). Instead, you want to build std::shared_ptr using the returned raw pointer.

+6
source

The code works, but it is ugly and fragile. Why mix pretty modern C ++ (smart pointers) with something archaic and dangerous like C-style? You are much better off calling reset :

 some_class.reset(LibraryMethod()); 

The above assumes (as your question indicates) that you have already declared std::shared_ptr<SomeClass> some_class; somewhere and want to reassign it. If you create some_class just before calling LibraryMethod , it is much better to initialize it directly:

 std::shared_ptr<SomeClass> some_class(LibraryMethod()); 

This is equivalent to CoryKramer answer .


Note, however, that there is a big assumption in all of this code: LibraryMethod returns a pointer to memory allocated dynamically via new , and that its caller is responsible for freeing this memory by calling delete .

+3
source

In your case, the correct way should be to use the shared_ptr constructor:

 std::shared_ptr<SomeClass> sPtr(LibraryMethod()); 

BUT you should first know what the correct LibraryMethod() pointer LibraryMethod() , most libraries return a raw pointer to say β€œhei”, you can access this object through this pointer, but don’t look, I am still responsible for managing this, therefore ... do not delete it! "

If you are sure that after this call you are responsible for managing it, then well, you can use shared_ptr with peace of mind.

+3
source

Is the above correct technique?

Yes, considering that LibraryMethod allocates a resource using new , and the library user is responsible for deleting it. Wrapping source pointers with smart pointers is widely used for legacy libraries.

Am I causing a leak here?

Not if you do it right. I agree with the other answers, but you can also:

 std::shared_ptr<SomeClass> some_class(LibraryMethod()); 

Are there any better methods to handle such a scenario?

One thing to consider carefully is the ownership of the resource allocated by LibraryMethod . Some argue that shared_ptr is evil in the sense that it is just a more convenient way of introducing a global with dependencies that are difficult to track. See this conversation or this one @ 8: 40 for example, Sean Parent. Instead, you can use std :: unique_ptr if there is an object in the code that consumes and owns the resource.

Also, if LibraryMethod can throw exceptions, you should handle this case accordingly.

+2
source

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


All Articles