Commit 0c09d5d6e495f3cdd3ebc4a61391d062462d4f03
1 parent
b5044584
Use static member functions instead of static members for avoid static initialization order fiasco
Showing
3 changed files
with
47 additions
and
61 deletions
include/GModelTemporalRegistry.hpp
| ... | ... | @@ -75,14 +75,26 @@ protected: |
| 75 | 75 | void free_members(void); |
| 76 | 76 | |
| 77 | 77 | private: |
| 78 | - // Private members | |
| 79 | - static int m_number; //!< Number of models in registry | |
| 80 | - static std::string* m_names; //!< Model names | |
| 81 | - static const GModelTemporal** m_models; //!< Pointer to seed models | |
| 78 | + // Private members (the private members have been implement as static | |
| 79 | + // methods to avoid the static initialization order fiasco of static | |
| 80 | + // members; using static methods we follow the "construct on first use | |
| 81 | + // idiom") | |
| 82 | + //static int m_number; //!< Number of models in registry | |
| 83 | + //static std::string* m_names; //!< Model names | |
| 84 | + //static const GModelTemporal** m_models; //!< Pointer to seed models | |
| 82 | 85 | //static GRegistryPointer<std::string> m_names; |
| 83 | - //static GRegistryPointer<const GModelTemporal*> m_models; | |
| 84 | - //static std::auto_ptr<std::string> m_names; | |
| 85 | - //static std::auto_ptr<const GModelTemporal*> m_models; | |
| 86 | + static int& number() { | |
| 87 | + static int m_number = 0; | |
| 88 | + return m_number; | |
| 89 | + }; | |
| 90 | + static GRegistryPointer<std::string>& names() { | |
| 91 | + static GRegistryPointer<std::string> m_names; | |
| 92 | + return m_names; | |
| 93 | + }; | |
| 94 | + static GRegistryPointer<const GModelTemporal*>& models() { | |
| 95 | + static GRegistryPointer<const GModelTemporal*> m_models; | |
| 96 | + return m_models; | |
| 97 | + }; | |
| 86 | 98 | }; |
| 87 | 99 | |
| 88 | 100 | |
| ... | ... | @@ -96,7 +108,7 @@ private: |
| 96 | 108 | inline |
| 97 | 109 | int GModelTemporalRegistry::size(void) const |
| 98 | 110 | { |
| 99 | - return m_number; | |
| 111 | + return number(); | |
| 100 | 112 | } |
| 101 | 113 | |
| 102 | 114 | #endif /* GMODELTEMPORALREGISTRY_HPP */ | ... | ... |
include/GRegistry.hpp
| ... | ... | @@ -44,8 +44,8 @@ class GRegistryPointer { |
| 44 | 44 | |
| 45 | 45 | public: |
| 46 | 46 | // Constructors and destructors |
| 47 | - explicit GRegistryPointer(T* ptr = NULL) : m_ptr(ptr) { } | |
| 48 | - GRegistryPointer(const GRegistryPointer<T>& ptr) : m_ptr(ptr.m_ptr) {} | |
| 47 | + GRegistryPointer(void) : m_ptr(0) { } | |
| 48 | + GRegistryPointer(const GRegistryPointer<T>& ptr) : m_ptr(ptr.m_ptr) { } | |
| 49 | 49 | virtual ~GRegistryPointer(void) { free_members(); } |
| 50 | 50 | |
| 51 | 51 | // Operators | ... | ... |
src/model/GModelTemporalRegistry.cpp
| ... | ... | @@ -32,15 +32,6 @@ |
| 32 | 32 | #include "GException.hpp" |
| 33 | 33 | #include "GTools.hpp" |
| 34 | 34 | |
| 35 | -/* __ Static members _____________________________________________________ */ | |
| 36 | -int GModelTemporalRegistry::m_number(0); | |
| 37 | -std::string* GModelTemporalRegistry::m_names(0); | |
| 38 | -const GModelTemporal** GModelTemporalRegistry::m_models(0); | |
| 39 | -//GRegistryPointer<std::string> GModelTemporalRegistry::m_names(0); | |
| 40 | -//GRegistryPointer<const GModelTemporal*> GModelTemporalRegistry::m_models(0); | |
| 41 | -//std::auto_ptr<std::string> GModelTemporalRegistry::m_names(0); | |
| 42 | -//std::auto_ptr<const GModelTemporal*> GModelTemporalRegistry::m_models(0); | |
| 43 | - | |
| 44 | 35 | /* __ Method name definitions ____________________________________________ */ |
| 45 | 36 | #define G_NAME "GModelTemporalRegistry::name(int&)" |
| 46 | 37 | |
| ... | ... | @@ -69,9 +60,8 @@ GModelTemporalRegistry::GModelTemporalRegistry(void) |
| 69 | 60 | // Debug option: Show actual registry |
| 70 | 61 | #if G_DEBUG_REGISTRY |
| 71 | 62 | std::cout << "GModelTemporalRegistry(void): "; |
| 72 | - for (int i = 0; i < m_number; ++i) { | |
| 73 | - std::cout << "\"" << m_names[i] << "\" "; | |
| 74 | -// std::cout << "\"" << (m_names.get())[i] << "\" "; | |
| 63 | + for (int i = 0; i < number(); ++i) { | |
| 64 | + std::cout << "\"" << names()[i] << "\" "; | |
| 75 | 65 | } |
| 76 | 66 | std::cout << std::endl; |
| 77 | 67 | #endif |
| ... | ... | @@ -96,44 +86,33 @@ GModelTemporalRegistry::GModelTemporalRegistry(const GModelTemporal* model) |
| 96 | 86 | std::cout << "GModelTemporalRegistry(const GModelTemporal*): "; |
| 97 | 87 | std::cout << "add \"" << model->type() << "\" to registry." << std::endl; |
| 98 | 88 | #endif |
| 99 | - | |
| 100 | - // Allocate new old registry | |
| 101 | - std::string* new_names = new std::string[m_number+1]; | |
| 102 | - const GModelTemporal** new_models = new const GModelTemporal*[m_number+1]; | |
| 89 | + | |
| 90 | + // Allocate new registry | |
| 91 | + std::string* new_names = new std::string[number()+1]; | |
| 92 | + const GModelTemporal** new_models = new const GModelTemporal*[number()+1]; | |
| 103 | 93 | |
| 104 | 94 | // Save old registry |
| 105 | - for (int i = 0; i < m_number; ++i) { | |
| 106 | - new_names[i] = m_names[i]; | |
| 107 | - new_models[i] = m_models[i]; | |
| 108 | -// new_names[i] = (m_names.get())[i]; | |
| 109 | -// new_models[i] = (m_models.get())[i]; | |
| 95 | + for (int i = 0; i < number(); ++i) { | |
| 96 | + new_names[i] = names()[i]; | |
| 97 | + new_models[i] = models()[i]; | |
| 110 | 98 | } |
| 111 | 99 | |
| 112 | 100 | // Add new model to registry |
| 113 | - new_names[m_number] = model->type(); | |
| 114 | - new_models[m_number] = model; | |
| 115 | - | |
| 116 | - // Delete old registry | |
| 117 | - if (m_names != NULL) delete [] m_names; | |
| 118 | - if (m_models != NULL) delete [] m_models; | |
| 101 | + new_names[number()] = model->type(); | |
| 102 | + new_models[number()] = model; | |
| 119 | 103 | |
| 120 | 104 | // Set pointers on new registry |
| 121 | - m_names = new_names; | |
| 122 | - m_models = new_models; | |
| 123 | - //m_names.assign(new_names); | |
| 124 | - //m_models.assign(new_models); | |
| 125 | - //m_names.reset(new_names); | |
| 126 | - //m_models.reset(new_models); | |
| 105 | + names().assign(new_names); | |
| 106 | + models().assign(new_models); | |
| 127 | 107 | |
| 128 | 108 | // Increment number of models in registry |
| 129 | - m_number++; | |
| 109 | + number()++; | |
| 130 | 110 | |
| 131 | 111 | // Debug option: Show actual registry |
| 132 | 112 | #if G_DEBUG_REGISTRY |
| 133 | 113 | std::cout << "GModelTemporalRegistry(const GModelTemporal*): "; |
| 134 | - for (int i = 0; i < m_number; ++i) { | |
| 135 | - std::cout << "\"" << m_names[i] << "\" "; | |
| 136 | -// std::cout << "\"" << (m_names.get())[i] << "\" "; | |
| 114 | + for (int i = 0; i < number(); ++i) { | |
| 115 | + std::cout << "\"" << names()[i] << "\" "; | |
| 137 | 116 | } |
| 138 | 117 | std::cout << std::endl; |
| 139 | 118 | #endif |
| ... | ... | @@ -229,14 +208,12 @@ GModelTemporal* GModelTemporalRegistry::alloc(const std::string& name) const |
| 229 | 208 | GModelTemporal* model = NULL; |
| 230 | 209 | |
| 231 | 210 | // Search for model in registry |
| 232 | - for (int i = 0; i < m_number; ++i) { | |
| 233 | - if (m_names[i] == name) { | |
| 234 | -// if ((m_names.get())[i] == name) { | |
| 235 | - model = m_models[i]->clone(); | |
| 236 | -// model = (m_models.get())[i]->clone(); | |
| 211 | + for (int i = 0; i < number(); ++i) { | |
| 212 | + if (names()[i] == name) { | |
| 213 | + model = models()[i]->clone(); | |
| 237 | 214 | break; |
| 238 | 215 | } |
| 239 | - } | |
| 216 | + } | |
| 240 | 217 | |
| 241 | 218 | // Return temporal model |
| 242 | 219 | return model; |
| ... | ... | @@ -262,8 +239,7 @@ std::string GModelTemporalRegistry::name(const int& index) const |
| 262 | 239 | #endif |
| 263 | 240 | |
| 264 | 241 | // Return name |
| 265 | - return (m_names[index]); | |
| 266 | -// return ((m_names.get())[index]); | |
| 242 | + return (names()[index]); | |
| 267 | 243 | } |
| 268 | 244 | |
| 269 | 245 | |
| ... | ... | @@ -286,14 +262,12 @@ std::string GModelTemporalRegistry::print(const GChatter& chatter) const |
| 286 | 262 | |
| 287 | 263 | // Append information |
| 288 | 264 | result.append("\n"+gammalib::parformat("Number of models")); |
| 289 | - result.append(gammalib::str(m_number)); | |
| 265 | + result.append(gammalib::str(number())); | |
| 290 | 266 | |
| 291 | 267 | // Append models |
| 292 | - for (int i = 0; i < m_number; ++i) { | |
| 293 | - result.append("\n"+gammalib::parformat(m_names[i])); | |
| 294 | -// result.append("\n"+gammalib::parformat((m_names.get())[i])); | |
| 295 | - result.append(m_models[i]->type()); | |
| 296 | -// result.append((m_models.get())[i]->type()); | |
| 268 | + for (int i = 0; i < number(); ++i) { | |
| 269 | + result.append("\n"+gammalib::parformat(names()[i])); | |
| 270 | + result.append(models()[i]->type()); | |
| 297 | 271 | } |
| 298 | 272 | |
| 299 | 273 | } // endif: chatter was not silent | ... | ... |