I've inherited some legacy code with lots of global variables as well as lots of global functions using them.
I intend to refactor the code into something cleaner, but I see 4 ways of doing it (which I've put below in a simplified form) and I have no idea about the pros and cons of each one.
Can anyone help me get a clearer picture?
Possibility A (free functions and variables):
// Basically it's still global functions and variables
// but now the global namespace isn't polluted
// and the variables are only accessible from onefile
namespace functionality
{
namespace
{
int x = 0;
double y = 0.;
}
int f()
{
return doStuff(x,y);
}
double g()
{
return doOtherStuff(x,y);
}
}
// Called like this
auto val = functionality::f();
auto otherVal = functionality::g();
Possibility B (class with static members):
class Functionality
{
private:
static int x = 0;
static double y = 0.;
public:
static int f()
{
return doStuff(x,y);
}
static double g()
{
doOtherStuff(x,y);
}
};
// Called like this
auto val = Functionality::f();
auto otherVal = Functionality::g();
Possibility C (singleton):
class Functionality
{
private:
int x = 0;
double y = 0.;
Functionality()
{}
public:
static Functionality& getSingleton()
{
static Functionality singleton;
return singleton;
}
int f()
{
return doStuff(x,y);
}
double g()
{
doOtherStuff(x,y);
}
};
// Called like this
auto val = Functionality::getSingleton.f();
auto otherVal = Functionality::getSingleton.g();
Possibility D (mix of B and C):
class Functionality
{
private:
int x = 0;
double y = 0.;
Functionality()
{}
static Functionality& getSingleton()
{
static Functionality singleton;
return singleton;
}
int f_impl()
{
return doStuff(x,y);
}
double g_impl()
{
doOtherStuff(x,y);
}
public:
static int f()
{
return getSingleton.f();
}
static double g()
{
return getSingleton.g();
}
};
// Called like this
auto val = Functionality::f();
auto otherVal = Functionality::g();
So, what are the pros and cons of each one? In particular, is there an actual difference between A, B and D?