Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Optional reference member - is it possible?

I have the following class

class CItem
{
    public:
        CItem(CRegistry &Registry) _Registry(Registry) {Registry.Register();}
        ~CItem() {_Registry.Unregister()};


    private:
        CRegistry &_Registry;
}

After a while it turns out that not all CItem objects need to be registered so I need a version of CItem which does not requires Registry in constructor (and of course of the registration code). How can I implement this? The only solution I can see here is to get and keep Registry as a pointer. Is there more elegant solution, like using templates, etc (I don't like switching from reference to pointer)?

like image 202
jackhab Avatar asked Nov 30 '22 12:11

jackhab


1 Answers

If you want to keep a single class, just change the attribute into a raw pointer and allow it to be null. As Neil points out, there is a widespread unjustified jihad against raw pointers that is not fully justified. Use a raw pointer and clearly document (comment) that the object holds no ownership of the pointed memory so that no one feels like adding a delete in your destructor at a later time.

All other solutions will be worse than using a pointer internally. It is an implementation detail. Also consider whether it makes sense. Your code will no longer be able to assume that the pointer is valid and it will complicate the logic inside your class.

class CItem
{
public:
   CItem(CRegistry &Registry) : _Registry(&Registry) {Registry->Register();}
   CItem() : _Registry(0) {}
   ~CItem() { if ( _Registry ) _Registry->Unregister(); }

private:
   CRegistry *_Registry; // Pointer is not owned. Do not delete!
};

As a last note: do not prefix attributes with a single underscore as they are reserved by the standard for C++ implementations (compiler and standard libraries)

like image 143
David Rodríguez - dribeas Avatar answered Dec 19 '22 09:12

David Rodríguez - dribeas