Dragonfly Q&A

Is there a reason for repeatedly creating local variables for the various singletons?

1 like 0 dislike
I've noticed that in many of the helper functions, local variables are created to hold the addresses of the various singletons, even multiple times in one class. Is there a reason that one might not want to create one class wide field in the header file, assign it in the constructor and then just reuse that class variable in each function intead of calling getInstance() mulitple times?
asked Sep 2, 2014 in Tutorial by remckenna

1 Answer

0 like 0 dislike
Best answer

While this does sound tempting, it cannot be done since accesses to the Manager singletons are references, and C++ references need to be initialized when they are declared.

As an example, consider this code:

#include "LogManager.h"
#include "Object.h"

class MyObject : public Object {

  // Uninitialized reference member!
  // References must be assigned upon initialization.

  LogManager &log_manager1;  

  // LogManager::getInstance() cannot appear in a constant-expression!
  // A function call cannot appear in a constant-expression.

  LogManager &log_manager2 = LogManager::getInstance();


The above code would not compile for the reasons indicated in the comments.

The first declaration of log_manager1 is not allowed since it is a reference and C++ references must be assigned/initialized when they are declared.

The second declaration of log_manager2 does attempt to assign the reference when declared, but the right hand side of this expression must be a constant expression. The assignment here is different than if the same code were inside a method (say, in Hero::step()) because the code above needs to be resolved when MyObject is instantiated.

There are, however, a couple of options that could be used when dealing with Dragonfly Managers.  Instead of assigning the Manager instance to a reference, the static method could instead be used.  For example, the statements:

  LogManager &log_manager = LogManager::getInstance();
  log_manager.writeLog("This is a message");

Could be replaced with:

  LogManager::getInstance().writeLog("This is a message");

Or, a #define could be used to shorten the code even more:

#define LM LogManager::getInstance()

  LM.writeLog("This is a message");

The advantage for either of the above approaches is that there are fewer lines of code to read and understand.  The disadvantage is that functionality is harder to understand by inspection, particularly in the case of the #define.  Throughout the Tutorial, I've chosen to use the more verbose but easier to understand case of declaring the reference and calling getInstance() each time.  I'd recommend this practice, at least initially, as it is the most explicit and clear in terms of what the code is doing.


answered Sep 3, 2014 by claypool
selected Sep 3, 2014 by remckenna
More information about Dragonfly can be found on the Dragonfly Home Page.