Skip to content

Instantly share code, notes, and snippets.

@nixiz
Last active August 14, 2018 15:49
Show Gist options
  • Save nixiz/414a8a89692a4abee6aba6fe70da9b5e to your computer and use it in GitHub Desktop.
Save nixiz/414a8a89692a4abee6aba6fe70da9b5e to your computer and use it in GitHub Desktop.
What should happen during program shutdown if one Singleton's destructor tries to use another Singleton that's already been destroyed? The problem defined by Andrei Alexandrescu in book: Modern C++ Design: Generic Programming and Design Patterns Applied
#include <stdio.h>
/*
* Simple template singleton base class
*/
template<typename T>
class Singleton {
protected:
Singleton() = default;
Singleton(const Singleton&) = delete;
Singleton& operator=(const Singleton&) = delete;
~Singleton() = default;
public:
static T& getInstance()
{
static T instance;
return instance;
}
};
class A : public Singleton<A> {
public:
~A() {
printf("\nDtor::A");
}
void foo() {
printf("\nA::foo() called");
}
private:
friend class Singleton<A>;
A() {
printf("\nCtor::A");
}
};
class B : public Singleton<B> {
public:
~B() {
printf("\nDtor::B");
// in here b uses singleton A's foo method
// so what if A's static instance already been destructed?
// how to guarantee dtor in correct order static instances
A::getInstance().foo();
}
void bar() {
printf("\nB::bar() called");
}
private:
friend class Singleton<B>;
B() {
printf("\nCtor::B");
}
};
int main()
{
// create singleton classes
A::getInstance().foo();
B::getInstance().bar();
return 0;
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment