Commit 0c09d5d6e495f3cdd3ebc4a61391d062462d4f03

Authored by Jürgen Knödlseder
1 parent b5044584

Use static member functions instead of static members for avoid static initialization order fiasco

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&amp; 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&amp; 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&amp; 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
... ...