Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Function returning reference, what to return on failure?

Tags:

c++

singleton

As a consequence of the design of a framework I'm targeting with a plugin, I've implemented a part of my code as a singleton. This class is responsible for handling connections to an external program with which I'm communicating from within the framework.

Enabling the external communication is a runtime setting, however, and if it is disabled, I don't want to allow access to it from models within the framework. I've implemented it using the version which is frequently recommended here:

class Communicator {
public: 
    static Communicator& getInstance() {
        static Communicator instance;
        return instance;
    }
    // ...
private: 
    static bool ServiceEnabled;
    // Constructors, operator=, etc ...
}

Now, given that ServiceEnabled is false, I don't want to allow getInstance to return a valid Communicator. But since I return a reference, I can't simply return 0 or some such... What would proper behaviour be? Note that it is perfectly valid to continue execution even if ServiceEnabled is false, so I can't just abort if it is.

like image 269
carlpett Avatar asked Feb 26 '26 05:02

carlpett


2 Answers

Add a public function

static bool IsServiceEnabled();

and throw an exception in getInstance, when it's called while ServiceEnabled == false;

like image 50
Henrik Avatar answered Feb 27 '26 18:02

Henrik


There are, actually, many possibilities... Here is the beginning of a list, in no particular order.

Pointer

class Communicator {
public:
  static Communicator const* Instance(); // returns 0 if not Enabled
};

This can actually be replaced by a "safer" pointer type (that assert/throw if the pointer is null and someone tries to use it).

Query + Throw

class Communicator {
public:
  static bool IsEnabled();
  static Communicator const& Instance(); // throw if not Enabled
};

Null Object

class Communicator {
public:
  static Communicator const& Instance(); //returns a null instance if not Enabled

  void doit() { if (!enabled) { return; } }
};

I personally do not like the last one much, because by hiding away the fact that it was not enabled you may prevent users from noticing the problem early on. Think of a transactional system convinced of having registered its transactions when it sent everything to /dev/null...

like image 45
Matthieu M. Avatar answered Feb 27 '26 19:02

Matthieu M.



Donate For Us

If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!