Using unthinkable pointers in modern C ++

Short version:
Is there an acceptable reason for using unwashed pointers in modern C ++?

Long version:
we have a huge product that contains a lot of old C ++ code, and now we are trying to reorganize it to the modern era of C ++. Along with all the old-fashioned code, there are a huge number of pointers passing around (mostly with SAL annotations to provide some sense of security), and I was wondering if we should change them all to smart pointers or maybe leave some of them?
Trying to convert some of these codes, I ended up with code that is simply argued for using smart pointers .

So the question is: is there such a thing as using smart pointers?
Or, in other words: is there an acceptable scenario for unwashed pointers these days?

+6
source share
5 answers

Smart pointers ( unique_ptr and shared_ptr ) must be OWNING pointers (i.e. responsible for destroying an object). The bottom line of their use is that any object created by new should be placed in ASAP's unique_ptr to prevent memory leaks. After that, unique_ptr should be moved:

  • or in shared_ptr , if the ownership should be shared,
  • or in unique_ptr , if the ownership is determined by the region (block or lifetime of the object).

release should be rare. If your code passes non-owner pointers, they should be:

  • raw pointers, if they can be null , (received by get )
  • if they cannot be null , (obtained by get )
  • unique_ptr by value, if the purpose of the call is to transfer ownership. (in this case you will need to move them)

Factory methods should return unique_ptr by value. (because then if you do not assign a return value to the factory method, the object is immediately de-allocated)

And check Ali's answer for links to some philosophical points of processing obsolete code. (That I totally agree)

+5
source

Yes, source pointers are still used as an “optional link”. That is, a T* is similar to a T& . None of them imply ownership, but T* may be nullptr .

+2
source

Short version:
Is there an acceptable reason for using unthinkable pointers in modern C ++?

Short answer:

Certainly, if they serve only for observation, that is , they do not own pointee. However, try using links instead of pointers even in this case; use pointers only if you really need to make them optional (initialize with null_ptr and then reassign later, for example).

Long version:
we have a huge product that contains a lot of old C ++ code, and now we are trying to reorganize it to the modern era of C ++. [...]

Long answer:

As I read these lines, this answer comes to mind:

I would like this answer to be postponed more than once. I would say: “[...] for every refactor that we have made, we can justify“ this particular change will make the real task that we are doing now easier. ”Instead of“ now it is cleaner for future work. ”

In short, don't do a lot of refactoring unless you really need to.

So the question is: is there such a thing as using smart pointers?

In my opinion, std::shared_ptr overused. It is very convenient to use, and it gives you the illusion that you do not need to think about ownership problems. But this is not the whole picture. I totally agree with Sean Parent : "a generic pointer is as good as a global variable." Generic pointers can also introduce very complex ownership problems, etc.

On the other hand, if you need to allocate something on the heap, use unique_ptr . You cannot abuse it if you really need heap allocation. In my experience, using unique_ptr also leads to more understandable and understandable code, as ownership issues become clear.

Interesting talks from Sean Parent on how to avoid / reduce the use of pointers:

Hope this helps.

+2
source

Check out the talks here: http://channel9.msdn.com/Events/GoingNative/2013 (especially the Stroustrup conversation).

The short answer is no, assuming "modern C ++" is> = C ++ 11

The long answer is not always the case, and trying to restructure a major project is almost always difficult. The way we think about problems is limited to the tools we need to solve. There are many cases when you do such refactoring, when it just makes sense to use pointers than to try to re-express the basic logic to be cool and intelligent. I think this is not the case when smart pointers are overused, and more cases where classes are used. YMMV; -)

0
source

Of course, for modern pointers, modern C ++ uses examples of use:

  • which should be compiled as pure C (although the implementation itself can use those C ++ functions that are not also C functions, such as classes or smart pointers).
  • which is extremely low, so low that even the simplest smart pointer proves that it is heavy

Of course, these are quite rare cases, and in most cases the most effective examples of pointers with smart pointers should be fine for the new code, BUT:

If the existing code works fine with raw pointers, why invest time to rewrite it and risk adding errors when converting it to a smart pointer using the version?

Do not use refactoring code that works just fine because the new code is better suited to modern programming standards. These programming standards do not exist on their own, but they simplify working with some code, so do not refactor, which will cost you more time than it can save you in the future.

This means: if you need more time to check which of these pointers can be safely converted to smart pointers, and which cannot, and to search for errors that may occur in your refactoring, which can save on future maintenance work due to for refactoring, and then just does not refactor and does not leave it as it is.

If refactoring will save more time than it costs only for some parts of the code base, consider only refactoring these parts of the code base.

0
source

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


All Articles