Skip to content

Instantly share code, notes, and snippets.

@vpiotr
Last active August 29, 2015 14:13
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save vpiotr/ee5ede22197962f72c3d to your computer and use it in GitHub Desktop.
Save vpiotr/ee5ede22197962f72c3d to your computer and use it in GitHub Desktop.
// C++11 singleton with lazy initialization & construction arguments
// Requires arguments to be initialized before usage (otherwise default values will be passed)
using namespace std;
// singleton with lazy initialization & construction arguments
template <typename Derived, typename Args>
class SingletonWithArgs
{
public:
static Derived *getInstance() {
static std::unique_ptr<Derived> instance(new Derived(*Args::getInstance()));
return instance.get();
}
protected:
SingletonWithArgs() = default;
SingletonWithArgs(const SingletonWithArgs&) = delete;
SingletonWithArgs& operator= (const SingletonWithArgs&) = delete;
};
// singleton with lazy initialization & no arguments
template <typename Derived>
class SingletonNoArgs
{
public:
static Derived* getInstance()
{
static std::unique_ptr<Derived> instance(new Derived());
return instance.get();
}
protected:
SingletonNoArgs() = default;
SingletonNoArgs(const SingletonNoArgs&) = delete;
SingletonNoArgs& operator= (const SingletonNoArgs&) = delete;
};
// --- derived class
// arguments to pass to derived class
class ConsoleLogArgs : public SingletonNoArgs<ConsoleLogArgs> {
public:
string prefix;
};
// derived class
class ConsoleLog : public SingletonWithArgs<ConsoleLog, ConsoleLogArgs> {
typedef SingletonWithArgs<ConsoleLog, ConsoleLogArgs> inherited;
public:
void addText(const std::string &a_text) {
cout << m_prefix << a_text;
}
protected:
ConsoleLog(const ConsoleLogArgs &args) {
m_prefix = args.prefix;
}
friend class inherited;
protected:
std::string m_prefix;
};
// -- usage
void foo() {
ConsoleLog::getInstance()->addText("Test");
}
int main(int argc, char* argv[])
{
//not possible:
// ConsoleLog log2;
//not possible:
// ConsoleLog log(*ConsoleLogArgs::getInstance());
//not possible:
// std::unique_ptr<ConsoleLog> log(new ConsoleLog(*ConsoleLogArgs::getInstance()));
ConsoleLogArgs::getInstance()->prefix = "log: ";
foo();
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment