From 0c09d5d6e495f3cdd3ebc4a61391d062462d4f03 Mon Sep 17 00:00:00 2001 From: Jürgen Knödlseder Date: Tue, 12 Nov 2013 00:07:45 +0100 Subject: [PATCH] Use static member functions instead of static members for avoid static initialization order fiasco --- include/GModelTemporalRegistry.hpp | 28 ++++++++++++++++++++-------- include/GRegistry.hpp | 4 ++-- src/model/GModelTemporalRegistry.cpp | 76 +++++++++++++++++++++++++--------------------------------------------------- 3 files changed, 47 insertions(+), 61 deletions(-) diff --git a/include/GModelTemporalRegistry.hpp b/include/GModelTemporalRegistry.hpp index 83f3e45..8c66b81 100644 --- a/include/GModelTemporalRegistry.hpp +++ b/include/GModelTemporalRegistry.hpp @@ -75,14 +75,26 @@ protected: void free_members(void); private: - // Private members - static int m_number; //!< Number of models in registry - static std::string* m_names; //!< Model names - static const GModelTemporal** m_models; //!< Pointer to seed models + // Private members (the private members have been implement as static + // methods to avoid the static initialization order fiasco of static + // members; using static methods we follow the "construct on first use + // idiom") + //static int m_number; //!< Number of models in registry + //static std::string* m_names; //!< Model names + //static const GModelTemporal** m_models; //!< Pointer to seed models //static GRegistryPointer m_names; - //static GRegistryPointer m_models; - //static std::auto_ptr m_names; - //static std::auto_ptr m_models; + static int& number() { + static int m_number = 0; + return m_number; + }; + static GRegistryPointer& names() { + static GRegistryPointer m_names; + return m_names; + }; + static GRegistryPointer& models() { + static GRegistryPointer m_models; + return m_models; + }; }; @@ -96,7 +108,7 @@ private: inline int GModelTemporalRegistry::size(void) const { - return m_number; + return number(); } #endif /* GMODELTEMPORALREGISTRY_HPP */ diff --git a/include/GRegistry.hpp b/include/GRegistry.hpp index 453a41d..96fb60c 100644 --- a/include/GRegistry.hpp +++ b/include/GRegistry.hpp @@ -44,8 +44,8 @@ class GRegistryPointer { public: // Constructors and destructors - explicit GRegistryPointer(T* ptr = NULL) : m_ptr(ptr) { } - GRegistryPointer(const GRegistryPointer& ptr) : m_ptr(ptr.m_ptr) {} + GRegistryPointer(void) : m_ptr(0) { } + GRegistryPointer(const GRegistryPointer& ptr) : m_ptr(ptr.m_ptr) { } virtual ~GRegistryPointer(void) { free_members(); } // Operators diff --git a/src/model/GModelTemporalRegistry.cpp b/src/model/GModelTemporalRegistry.cpp index 0c449f5..c84f034 100644 --- a/src/model/GModelTemporalRegistry.cpp +++ b/src/model/GModelTemporalRegistry.cpp @@ -32,15 +32,6 @@ #include "GException.hpp" #include "GTools.hpp" -/* __ Static members _____________________________________________________ */ -int GModelTemporalRegistry::m_number(0); -std::string* GModelTemporalRegistry::m_names(0); -const GModelTemporal** GModelTemporalRegistry::m_models(0); -//GRegistryPointer GModelTemporalRegistry::m_names(0); -//GRegistryPointer GModelTemporalRegistry::m_models(0); -//std::auto_ptr GModelTemporalRegistry::m_names(0); -//std::auto_ptr GModelTemporalRegistry::m_models(0); - /* __ Method name definitions ____________________________________________ */ #define G_NAME "GModelTemporalRegistry::name(int&)" @@ -69,9 +60,8 @@ GModelTemporalRegistry::GModelTemporalRegistry(void) // Debug option: Show actual registry #if G_DEBUG_REGISTRY std::cout << "GModelTemporalRegistry(void): "; - for (int i = 0; i < m_number; ++i) { - std::cout << "\"" << m_names[i] << "\" "; -// std::cout << "\"" << (m_names.get())[i] << "\" "; + for (int i = 0; i < number(); ++i) { + std::cout << "\"" << names()[i] << "\" "; } std::cout << std::endl; #endif @@ -96,44 +86,33 @@ GModelTemporalRegistry::GModelTemporalRegistry(const GModelTemporal* model) std::cout << "GModelTemporalRegistry(const GModelTemporal*): "; std::cout << "add \"" << model->type() << "\" to registry." << std::endl; #endif - - // Allocate new old registry - std::string* new_names = new std::string[m_number+1]; - const GModelTemporal** new_models = new const GModelTemporal*[m_number+1]; + + // Allocate new registry + std::string* new_names = new std::string[number()+1]; + const GModelTemporal** new_models = new const GModelTemporal*[number()+1]; // Save old registry - for (int i = 0; i < m_number; ++i) { - new_names[i] = m_names[i]; - new_models[i] = m_models[i]; -// new_names[i] = (m_names.get())[i]; -// new_models[i] = (m_models.get())[i]; + for (int i = 0; i < number(); ++i) { + new_names[i] = names()[i]; + new_models[i] = models()[i]; } // Add new model to registry - new_names[m_number] = model->type(); - new_models[m_number] = model; - - // Delete old registry - if (m_names != NULL) delete [] m_names; - if (m_models != NULL) delete [] m_models; + new_names[number()] = model->type(); + new_models[number()] = model; // Set pointers on new registry - m_names = new_names; - m_models = new_models; - //m_names.assign(new_names); - //m_models.assign(new_models); - //m_names.reset(new_names); - //m_models.reset(new_models); + names().assign(new_names); + models().assign(new_models); // Increment number of models in registry - m_number++; + number()++; // Debug option: Show actual registry #if G_DEBUG_REGISTRY std::cout << "GModelTemporalRegistry(const GModelTemporal*): "; - for (int i = 0; i < m_number; ++i) { - std::cout << "\"" << m_names[i] << "\" "; -// std::cout << "\"" << (m_names.get())[i] << "\" "; + for (int i = 0; i < number(); ++i) { + std::cout << "\"" << names()[i] << "\" "; } std::cout << std::endl; #endif @@ -229,14 +208,12 @@ GModelTemporal* GModelTemporalRegistry::alloc(const std::string& name) const GModelTemporal* model = NULL; // Search for model in registry - for (int i = 0; i < m_number; ++i) { - if (m_names[i] == name) { -// if ((m_names.get())[i] == name) { - model = m_models[i]->clone(); -// model = (m_models.get())[i]->clone(); + for (int i = 0; i < number(); ++i) { + if (names()[i] == name) { + model = models()[i]->clone(); break; } - } + } // Return temporal model return model; @@ -262,8 +239,7 @@ std::string GModelTemporalRegistry::name(const int& index) const #endif // Return name - return (m_names[index]); -// return ((m_names.get())[index]); + return (names()[index]); } @@ -286,14 +262,12 @@ std::string GModelTemporalRegistry::print(const GChatter& chatter) const // Append information result.append("\n"+gammalib::parformat("Number of models")); - result.append(gammalib::str(m_number)); + result.append(gammalib::str(number())); // Append models - for (int i = 0; i < m_number; ++i) { - result.append("\n"+gammalib::parformat(m_names[i])); -// result.append("\n"+gammalib::parformat((m_names.get())[i])); - result.append(m_models[i]->type()); -// result.append((m_models.get())[i]->type()); + for (int i = 0; i < number(); ++i) { + result.append("\n"+gammalib::parformat(names()[i])); + result.append(models()[i]->type()); } } // endif: chatter was not silent -- libgit2 0.21.4