[Suppose that]
"Log" class is declared and used as Singleton pattern, so is "App" class. Both classes have a "instance()" method that returns their object reference.
App class uses Log method(write). We can say that an App class has a dependency with a Log class.
In main code, call App::start().
[Question]
1. When an application terminates, an error(Debug Assertion Failed or Segmentation fault) occurs. why?
2. Guess the static objects destruction order when the application terminates(App>Log or Log>App ?).
3. Figure out a solution for this problem.
[Download]
[Source Code]
#include <stdio.h> #include <string.h> class Log { FILE* fp; private: Log() { fp = fopen("test.log", "wb"); } virtual ~Log() { fclose(fp); fp = NULL; } public: void write(const char* msg) { fwrite(msg, 1, strlen(msg), fp); }; public: static Log& instance() { static Log g_log; return g_log; } }; class App { private: App() { //Log::instance().write("App::App\n"); } virtual ~App() { Log::instance().write("App::~App\n"); } public: void start() { Log::instance().write("App::start\n"); } static App& instance() { static App g_app; return g_app; } }; int main() { App::instance().start(); return 0; }
[For more]
Template class name is changed from "Dependency" into "IHaveDependencyWith". Isn't it more clear? :)
// ---------------------------------------------------------------------------- // IHaveDependencyWith // ---------------------------------------------------------------------------- template <class T> class IHaveDependencyWith { public: /// class T must have static void dependency() IHaveDependencyWith() { T::dependency(); } virtual ~IHaveDependencyWith() {} };
Using the template class, you'd better inherit it in private mode instead of public mode to hiding calling dependency() method in other place.
// ---------------------------------------------------------------------------- // App // ---------------------------------------------------------------------------- class App : private IHaveDependencyWith<Log> {...
[How to fix this problem]
Tell App class that it has a dependency with Log class. See to following code(Declare "Dependency" template class and usage).
[Download]
static_error_fix_test.zip
[Source Code]