What type of (auto) pointer should I use?

I came across several questions where the answers state that using T * is never a better idea.

Although I already use RIIC a lot, there is one specific point in my code where I use T *. Reading about a few auto-pointers, I could not find one where I would say that I have a clear advantage from using it.

My scenario:

class MyClass { ... // This map is huge and only used by MyClass and // and several objects that are only used by MyClass as well. HashMap<string, Id> _hugeIdMap; ... void doSomething() { MyMapper mapper; // Here is what I pass. The reason I can't pass a const-ref is // that the mapper may possibly assign new IDs for keys not yet in the map. mapper.setIdMap(&_hugeIdMap); mapper.map(...); } } 

MyMapper now has a HashMap<...>* member, which - according to highly voted answers on questions about unrelated issues - is never a good idea (in fact, the converter goes beyond what the MyClass instance does and therefore I don't I think this is too big a problem. There is no new in mapper and no delete is required).

So what is the best alternative in this particular case?

+6
source share
3 answers

Personally, I think the source pointer (or link) is here. Smart pointers are associated with controlling the lifetime of the object that it points to, in which case MyMapper does not control the lifetime of this object, MyClass is. You also should not have a smart pointer pointing to an object that was not dynamically allocated (in this case, the hash map is not).

Personally, I would use something like the following:

 class MyMapper { public: MyMapper(HashMap<string, Id> &map) : _map(map) { } private: HashMap<string, Id> &_map }; 

Please note that this will prevent the use of the MyMapper assignment operator and can only work if it is acceptable to pass the HashMap in the constructor; if this is a problem, I would make the element a pointer (although I would still pass the argument as a reference and make _map(&map) in the list of initializers).

If it is possible that MyMapper or any other class using a hash map will go into MyClass , then you will need to start thinking about smart pointers. In this case, I would recommend std::shared_ptr , but you have to use it everywhere: _hugeIdMap should be shared_ptr for a dynamically distributed value, and not for a regular field without a pointer.


Update:

Since you said that using a link is unacceptable due to project coding standards, I would suggest just sticking to the raw pointer for the reasons mentioned above.

+8
source

Bare pointers (usually called raw pointers) are great when the object is not responsible for deleting the object. In the case of MyMapper, the pointer points to an object already owned by MyClass, and therefore it is absolutely normal not to delete it. The problem arises when you use raw pointers, when you intend to delete objects through them in which the problems lie. People ask questions only when they have problems, so you almost always see that they are used only in a problematic context, but the source pointers in a context that is not related to their own experience are wonderful.

+1
source

How to pass it to the constructor and save the link (or const-reference) to it? Thus, it becomes clear that you intend not to own the object.

The transfer of auto-pointers or general pointers is mainly intended to transfer ownership.

  • shared pointers indicate sharing
  • Auto-pointers indicate the responsibility of the recipient.
  • links indicate sender responsibility.
  • Empty pointers do not indicate anything.

About coding style:

our coding standards have an agreement that states that non-constant links are never passed.

If you use the C ++ link mechanism or the C ++ pointer mechanism, you pass the link (in English) to the internal storage, which will change. I think your coding standard is trying to tell you not to do this at all, not so much that you cannot use links for this, but you can do it differently.

0
source

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


All Articles