Static Pointer to Dynamically allocated array - c++

So the question is relatively straight forward, I have several semi-large lookup tables ~500kb a piece. Now these exact same tables are used by several class instantiations (maybe lots), with this in mind I don't want to store the same tables in each class. So I can either dump the entire tables onto the stack as 'static' members, or I can have 'static' pointers to these tables. In either case the constructor for the class will check whether they are initialized and do so if not. However, my question is, if I choose the static pointers to the tables (so as not to abuse the stack space) what is a good method for appropriately cleaning these up.
Also note that I have considered using boost::share_ptr, but opted not to, this is a very small project and I am not looking to add any dependencies.
Thanks

Static members will never be allocated on the stack. When you declare them (which of course, you do explicitly), they're assigned space somewhere (a data segment?).
If it makes sense that the lookup tables are members of the class, then make them static members!
When a class is instanced on the stack, the static member variables don't form part of the stack cost.
If, for instance, you want:
class MyClass {
...
static int LookUpTable[LARGENUM];
};
int MyClass:LookUpTable[LARGENUM];
When you instance MyClass on the stack, MyClass:LookUpTable points to the object that you've explicitly allocated on the last line of the codesample above. Best of all, there's no need to deallocate it, since it's essentially a global variable; it can't leak, since it's not on the heap.

If you don't free the memory for the tables at all, then when your program exits the OS will automatically throw away all memory allocated by your application. This is an appropriate strategy for handling memory that is allocated only once by your application.
Leaving the memory alone can actually improve performance too, because you won't waste time on shutdown trying to explicitly free everything and therefore possibly force a page in for all the memory you allocated. Just let the OS do it when you exit.

If these are lookup tables, the easiest solution is just to use std::vector:
class SomeClass {
/* ... */
static std::vector<element_type> static_data;
};
To initialize, you can do:
static_data.resize(numberOfElements);
// now initialize the contents
With this you can still do array-like access, as in:
SomeClass::static_data[42].foo();
And with any decent compiler, this should be as fast as a pointer to a native array.

Why don't you create a singleton class that manages the lookup tables? As it seems they need to be accessed by a number of classes; make the singleton the manager of the lookup tables accessible at global scope. Then all the classes can use the singleton getters/setters to manipulate the lookup tables. There are 3 advantages to this approach:-
If the static container size for the
lookup tables becomes large then the
default stack-size may ( 1MB on
Windows) lead to stack-overflow on
application statrt-up itself. Use a container that allocates dynamically.
If you plan to access the table via multiple-threads, the singleton class can be extended to accompany locked access.
You can also cleanup in the dtor of singleton during application exit.

I can think of several ways to approach for this depending upon what is trying to be accomplished.
If the data is static and fixed, using a static array which is global and initialized within the code would be a good approach. Everything is contained in the code and loaded when the program is started so it is available. Then all of the class which need access can access the information.
If the data is not static and needs to read in, an static STL structure, such as a vector, list or map would be good as it can grow as you add elements to the list. Some of these class provides lookup methods as well. Depending upon the data you are looking up, you may have to provide a structure and some operator to have the STL structures work correctly.
In either of the two case, you might what to make a static global class to read and contain the data. It can take care of managing initialization and access the data. You can use private members to indicate if the class has been read in and is available for use. If it has not, the class might be able to do the initialization by itself if it has enough information. The other class can call static function of the static global class to access the data. This provides encapsulation of the data, and then it can be used by several different classes without those classes needing to incorperate the large lookup table.

There are several possibilties with various advantages and disadvantages. I don't know what the table contains, so I'll call it an Entry.
If you just want the memory to be sure to go away when the program exits, use a global auto_ptr:
auto_ptr<Entry> pTable;
You can initialize it whenever you like, and it will automatically be deleted when the program exits. Unfortunately, it will pollute the global namespace.
It sounds like you are using the same table within multiple instances of the same class. In this case, it is usual to make it a static pointer of that class:
class MyClass {
...
protected:
static auto_ptr<Entry> pTable;
};
If you want it to be accessible in instances of different classes, then you might make it a static member of a function, these will also be deleted when the program exits, but the really nice thing is that it won't be initialized until the function is entered. I.e., the resource won't need to be allocated if the function is never called upon:
Entry* getTable() {
static auto_ptr<Entry> pTable = new Entry[ gNumEntries ];
return pTable;
}
You can do any of these with std::vector<Entry> rather than auto_ptr<Entry>, if you prefer, but the main advantage of that is that it can more easily be dynamically resized. That might not be something you value.

Related

Is there a rule of thumb to decide where to store my classes (i.e. what type of memory)?

Suppose I have a c++ program which with several classes which are related like this:
class Application
{
public:
// some functions
private:
BusinessLogic businessLogic;
// some variables
};
class BusinessLogic
{
public:
// some functions
private:
BusinessLogicSubClass1 businessLogicSubClass1;
BusinessLogicSubClass2 businessLogicSubClass2;
// some other member variables
};
BusinessLogicSubClass1
{
public:
// some functions
private:
SubClassOfSubClass1 subClassOfSubClass1;
// some other member variables
};
// etc.... (you get the idea I hope)
The point is, I know at compile time that there is an Application class that contains the BusinessLogic class which contains many sub classes. I also know that I only need one instance of the Application class. Now the question is how to decide on where to store such a class in memory?
As far as I know there are three main possibilities:
on the stack:
int main()
{
Application application;
// do something with application
return 0;
}
on the heap:
int main()
{
std::unique_ptr application = std::make_unique&ltApplication&gt();
// do something with application
return 0;
}
as a static:
int main()
{
static Application application;
// do something with application
return 0;
}
I read some information on the different types of memory. Based on what I read, I think it is not the best decision to store the application class on the stack. Mainly because the stack has a limited size and there is a very limited advantage of having the stack's automatic memory management (i.e. cleaning up variables that go out of scope) in this case.
I find it harder to decide however how to make the trade of between static and heap memory. In the simplified example above I think I go with static, because everything is known at compile time and static memory is said to be more efficient, compared to heap memory. (Does this way of thinking make any sense, or am I overlooking something here?)
However, there are some examples in which the choice becomes less evident. Suppose the application needs to be initialized via an .ini file. If you store the instance of the Application class on the heap, it will be possible to pass the initialization values via the constructor:
int main
{
IniFileReader reader;
InitializationValues iniValues = reader.GetIniValues();
std::unique_ptr application = std::make_unique&ltApplication2&gt(iniValues);
// do something with application
return 0;
}
As far as I know, constructor initialization is considered to be better in terms of design than using some Init function like this:
int main
{
static Application3 application;
IniFileReader reader;
InitializationValues iniValues = reader.GetIniValues();
application.Init(iniValues);
// do something with application
return 0;
}
So here the choice is between cleaner code or a more efficient program. I realize this is sort of trade off is very much dependent on what type of application you intend to build.
What I am looking for is, if there are perhaps some rules of thumb or a sort of flow chart to decide where to store your classes?
Some (not necessarily good) examples of such rules could be:
if you know everything about a class at compile time and you know there is only one instance, try to always store it as a static.
always use the heap for objects that are shared between different threads.
it does not really matter in this or that case, so chose for cleaner code.
And secondly, are there any general guidelines or design principles on where to put the static classes? I find it hard to decide where to put a static class if they need to be accessed by more than one other class. Globals are generally considered bad design for instance.
A practical example of such a dilemma, can be found in the following article on the state design pattern: https://gameprogrammingpatterns.com/state.html --> see subsection static states
I am not sure if the authors choice to put a static instance of each state in the base class is the best design. He also admits to put them there "for no particular reason". Any suggestions for a better place? Make a sort of state-database class? Make a singleton of each state?
edit: changed mistake in code pointed out by Neil Butterworth
One very common way to handle your situation is to use a Singleton design pattern. you can find lots of good references on stack overflow, or via a simple google search. Take a look at this one for example. For you it would look something like this:
class Application
{
public:
static Application& getInstance()
{
static Application instance;
return instance;
}
private:
Application() {}
...
};
For dynamic parameters, I'm not sure I would agree that it's always better to initialize in the constructor, but the details really matter for this. There are cases where it does make sense, and cases where it doesn't. In the singleton case you almost always need some sort of separate "Init" call since you don't want to pass construction arguments on every call to getInstance().
To your question about "heap" versus "static". Assuming you really are only creating one Application instance, and you're running on a "desktop" OS like Linux/Window/MacOS, there will be no meaningful difference in runtime performance between these two. Uninitialized static variables are usually placed in .bss, and the first thing the OS will do when launching your process is dynamically allocate a bunch of pages to make space for the various data sections in your program. Not a whole lot different from what you're doing in code (i.e. a one-time dynamic memory allocation).

What's better to use and why?

class MyClass {
private:
unsigned int currentTimeMS;
public:
void update() {
currentTimeMS = getTimeMS();
// ...
}
};
class MyClass {
public:
void update() {
unsigned int currentTimeMS = getTimeMS();
// ...
}
};
update() calls in main game loop so in the second case we get a lot of allocation operations (unsigned int currentTimeMS). In the first case we get only one allocate and use that allocated variable before.
Which of this code better to use and why?
I recommend the second variant because it is stateless and the scope of the variable is smaller. Use the first one only if you really experience a performance issue, which I consider unlikely.
If you do not modify the variable value later, you should also consider to make it const in order to express this intent in your code and to give the compiler additional optimization options.
It depends upon your needs. If currentTimeMS is needed only temporarily in the update(), then surely declare it there. (in your case, #option2)
But if it's value is needed for the instance of the class (i.e. being used in some other method), then you should declare it as a field (in your case, #option1).
In the first example, you are saving the state of this class object. In the second one, you're not, so the currentTime will be lost the instant update() is called.
It is really up to you to decide which one you need.
The first case is defining a member variable the second a local variable. Basic class stuff. A private member variable is available to any function (method) in that class. a local variable is only available in the function in which it is declared.
Which of this code better to use and why?
First and foremost, the cited code is at best a tiny micro-optimization. Don't worry about such things unless you have to.
In fact, this is most likely a disoptimization. Sometimes automatic variables are allocated on the stack. Stack allocation is extremely fast (and even free sometimes). There is no need to worry. Other times, the compiler may place a small automatic variable such the unsigned int used here in a register. There's no allocation whatsoever.
Compare that to making the variable a data member of the class, and solely for the purpose of avoiding that allocation. Accessing that variable involves going through the this pointer. Pointer dereference has a cost, potentially well beyond that of adding an offset to a pointer. The dereference might result in a cache miss. Even worse, this dereferencing may well be performed every time the variable is referenced.
That said, sometimes it is better to create data members solely for the purpose of avoiding automatic variables in various member functions. Large arrays declared as local automatic variables might well result in stack overflow. Note, however, that making double big_array[2000][2000] a data member of MyClass will most likely make it impossible to have a variable of type MyClass be declared as a local automatic variable in some function.
The standard solution to the problems created by placing large arrays on the stack is to instead allocate them on the heap. This leads to another place where creating a data member to avoid a local variable can be beneficial. While stack allocation is extremely fast, heap allocation (e.g., new) is quite slow. A member function that is called repeatedly may benefit by making the automatic variable std::unique_ptr<double> big_array = std::make_unique<double>(2000*2000) a data member of MyClass.
Note that neither of the above applies to the sample code in the question. Note also that the last concern (making an heap-allocated variable a data member so as to avoid repeated allocations and deallocations) means that the code has to go through the this pointer to access that memory. In tight code, I've sometimes been forced to create a local automatic pointer variable such as double* local_pointer = this->some_pointer_member to avoid repeated traversals through this.

How to decide what goes on stack?

Say I have a C++ class called MainComponent and it has a few classes inside of it: WindowClass, InputClass, GameClass. The main function is setup like so:
int main()
{
MainComponent app;
app.start(); // Initializes the MainComponent class, opens window, starts game and all that.
return 0;
}
The MainComponent class is expected to possibly get very big because of included objects of GameClass and such. Should MainComponent app be dynamically allocated with new? or should I allocate the GameClass objects with new inside the MainComponent class? or is it just fine to leave it on the stack as long as it runs fine or what?
Depends on what 'big' means. This link shows the default stack size limits for some OSes. You'll want to make sure that the size MainComponent allocates on the stack is well below any of these numbers.
Further, if there are certain things being dynamically created, or certain arrays/assets that are too large, which fall under MainComponent or another struct that is below MainComponent, then you can always heap-allocate that struct/array/class while still keeping MainComponent itself on the stack.
Conceptually, keeping MainComponent on the stack makes more sense as its lifecycle is being modeled exactly by its scope in the main function.
To answer your more general question, How to decide what goes on the stack?, consider three aspects:
Ownership. Is the ownership of a particular data structure clear? Does it explicitly belong to a particular function (and its descendants), or a particular struct/class and can be modeled with RAII?
Lifecycle. Is the particular data structure expected to exist within a timeline that closely resembles a lifetime of the class that created it, or the function that created it? What is the scope?
Is the size known at compile-time? This comes up when allocating arrays of a variable size. This is the case with many STL containers. In that case, the basic struct/class includes a few things on the stack and then maintains pointers to heap-allocated structures.
You said:
MainComponent class is expected to possibly get very big because of
included objects of GameClass
object size is constant. for example: empty std::string has the same sizeof as very long std::string, it is the same for any object.
the sizeof(object) is the only bytes it take on the stack. all the rest anyway goes to the heap.
so if you reach to stack limits and got stack overflow exceptions, then you should try to move some objects to heap. or if it is a single object (like your MainComponent class appear to be), you can also use the singleton pattern, or just declare it as static, to remove it from the stack to other segments of memory.

Qt C++: Global objects vs. reference chain

Currently I'm using singleton pattern for certain global objects in my application (Qt application for Symbian environment). However, because of some problems (C++ checking singleton pointers) it looks like that I have to change the logic.
I have 3 classes (logger, settings and container for some temp data) that I need to access via multiple different objects. Currently they are all created using singleton pattern. The logger basically is just one public method Log() with some internal logic when the settings and container have multiple get/set methods with some additional logic (e.g. QFileSystemWatcher). In addition, logger and settings have some cross-reference (e.g. logger needs some settings and settings logs errors).
Currently everything is "working fine", but there is still some problems that should be taken care of and it seems like they are not easy to implement for the singletons (possible memory leaks/null pointers). Now I have two different ways to handle this:
Create global objects (e.g. extern Logger log;) and initialize them on application startup.
Create objects in my main object and pass them to the children as a reference.
How I have few questions related to these:
Case 1.
Is it better to use stack or heap?
I'm going to declare those objects in some globals.h header using extern keyword. Is it ok?
I think in this case I have to remove that 2-way reference (settings needs logger and vice versa.)?
Case 2.
Should the objects be created in stack or heap in my main object (e.g. Logger *log = new Logger() vs Logger log;)
Long reference chains do not look nice (e.g. if i have to pass the object over multiple childrens).
What about in children?
If I pass a pointer to the children like this (I don't want to copy it, just use the "reference"): Children(Logger *log) : m_Log(log) what happens when the children is deleted? Should I set the local pointer m_Log to NULL or?
If I use stack I'll send reference to the child (Children(Logger &log) : m_Log(log)) where m_Log is a reference variable (Logger& m_Log;) right?
What should I note in terms of Qt memory management in this case?
Case 3.
Continue with singleton and initialize singleton objects during the startup (that would solve the null pointers). Then the only problem would possible memory leaks. My implementation follows this example. Is there a possible memory leak when I'm accessing the class using. What about singleton destruction?
#define LOG Logger::Instance()->Log
Thanks for reading.
Summary in simple terms:
if you use global objects, prefer the singleton pattern as a lesser evil. Note that a singleton should have global access! Dan-O's solution is not really a singleton pattern and it defeats the power of singletons even though he suggests it's no different.
if you use global objects, use lazy construction to avoid initialization order problems (initialize them when they are first accessed).
if you use singletons, instead of making everything that needs to be globally acccessible a singleton, consider making one singleton (Application) which stores the other globally-accessible objects (Logger, Settings, etc.) but don't make these objects singletons.
if you use locals, consider #3 anyway to avoid having to pass so many things around your system.
[Edit] I made a mistake and misplaced the static in safe_static which Dan pointed out. Thanks to him for that. I was blind for a moment and didn't realize the mistake based on the questions he was asking which lead to a most awkward situation. I tried to explain the lazy construction (aka lazy loading) behavior of singletons and he did not follow that I made a mistake and I still didn't realize I made one until the next day. I'm not interested in argument, only providing the best advice, but I must suggest strongly against some of the advice, particularly this case:
#include "log.h"
// declare your logger class here in the cpp file:
class Logger
{
// ... your impl as a singleton
}
void Log( const char* data )
{
Logger.getInstance().DoRealLog( data );
}
If you are going to go with globally accessible objects like singletons, then at least avoid this! It may have appealing syntax for the client, but it goes against a lot of the issues that singletons try to mitigate. You want a publicly accessible singleton instance and if you create a Log function like this, you want to pass your singleton instance to it. There are many reasons for this, but here is just one scenario: you might want to create separate Logger singletons with a common interface (error logger vs. warning logger vs. user message logger, e.g.). This method does not allow the client to choose and make use of a common logging interface. It also forces the singleton instance to be retrieved each time you log something, which makes it so that if you ever decide to steer away from singletons, there will be that much more code to rewrite.
Create global objects (e.g. extern
Logger log;) and initialize them on
application startup.
Try to avoid this at all costs for user-defined types, at least. Giving the object external linkage means that your logger will be constructed prior to the main entry point, and if it depends on any other global data like it, there's no guarantee about initialization order (your Logger could be accessing uninitialized objects).
Instead, consider this approach where access is initialization:
Logger& safe_static()
{
static Logger logger;
return logger;
}
Or in your case:
// Logger::instance is a static method
Logger& Logger::instance()
{
static Logger logger;
return logger;
}
In this function, the logger will not be created until the safe_static method is called. If you apply this to all similar data, you don't have to worry about initialization order since initialization order will follow the access pattern.
Note that despite its name, it isn't uber safe. This is still prone to thread-related problems if two threads concurrently call safe_static for the first time at the same time. One way to avoid this is to call these methods at the beginning of your application so that the data is guaranteed to be initialized post startup.
Create objects in my main object and
pass them to the children as a
reference.
It might become cumbersome and increase code size significantly to pass multiple objects around this way. Consider consolidating those objects into a single aggregate which has all the contextual data necessary.
Is it better to use stack or heap?
From a general standpoint, if your data is small and can fit comfortably in the stack, the stack is generally preferable. Stack allocation/deallocation is super fast (just incrementing/decrementing a stack register) and doesn't have any problems with thread contention.
However, since you are asking this specifically with respect to global objects, the stack doesn't make much sense. Perhaps you're asking whether you should use the heap or the data segment. The latter is fine for many cases and doesn't suffer from memory leak problems.
I'm going to declare those objects in
some globals.h header using extern
keyword. Is it ok?
No. #see safe_static above.
I think in this case I have to remove that 2-way reference (settings
needs logger and vice versa.)?
It's always good to try to eliminate circular dependencies from your code, but if you can't, #see safe_static.
If I pass a pointer to the children
like this (I don't want to copy it,
just use the "reference"):
Children(Logger *log) : m_Log(log)
what happens when the children is
deleted? Should I set the local
pointer m_Log to NULL or?
There's no need to do this. I'm assuming the memory management for the logger is not dealt with in the child. If you want a more robust solution, you can use boost::shared_ptr and reference counting to manage the logger's lifetime.
If I use stack I'll send reference to
the child (Children(Logger &log) :
m_Log(log)) where m_Log is a reference
variable (Logger& m_Log;) right?
You can pass by reference regardless of whether you use the stack or heap. However, storing pointers as members over references has the benefit that the compiler can generate a meaningful assignment operator (if applicable) in cases where it's desired but you don't need to explicitly define one yourself.
Case 3. Continue with singleton and
initialize singleton objects during
the startup (that would solve the null
pointers). Then the only problem would
possible memory leaks. My
implementation follows this example.
Is there a possible memory leak when
I'm accessing the class using. What
about singleton destruction?
Use boost::scoped_ptr or just store your classes as static objects inside an accessor function, like in safe_static above.
I found the other answer to be a little misleading. Here is mine, hopefully the SO community will determine which answer is better:
Is it better to use the stack or the heap?
Assuming by "the stack" you meant as a global (and thus in the data segment), don't worry about it, do whichever is easier for you. Remember that if you allocate it on the heap you do have to call delete.
I'm going to declare those objects in some globals.h header using extern keyword. Is it ok?
Why do you need to do that? The only classes that need access to the globals are the singletons themselves. The globals can even be static local variables, ala:
class c_Foo
{
static c_Foo& Instance()
{
static c_Foo g_foo; // static local variable will live for full life of the program, but cannot be accessed elsewhere, forcing others to use cFoo::Instance()
return g_foo;
}
};
If you don't want to use the static local then a private static member variable of type c_Foo (in my example) would be more appropriate than a straight global.
Remember, you want the lifetime of the class to be "global" (ie not destroyed until application exit), not the instance itself.
I think in this case I have to remove that 2-way reference (settings needs logger and vice versa.)?
All of the externed globals would have to be forward declared, but as I said above you don't need this header file.
Should the objects be created in stack or heap in my main object (e.g. Logger *log = new Logger() vs Logger log;)
I can't really answer this, don't worry about it again.
Long reference chains do not look nice
(e.g. if i have to pass the object
over multiple childrens).
What about in children?
Great points, you have realized that this would be a huge pain in the butt. In the case of something like a logger it would be hellish to pass references to every module just so they could spit out logging info. More appropriate would be a single static "Log" function ala C, if your logger has useful state then make it a singleton that is only visible to your log function. You can declare and implement your entire logger class in the same .cpp file that you implement your log function in. Then nothing else will be aware of this special functionality.
Here is what I mean:
file: log.h
#ifndef LOG_H
#define LOG_H
void Log( const char* data ); // or QString or whatever you're passing to your logger
#endif//LOG_H
file: log.cpp
#include "log.h"
// declare your logger class here in the cpp file:
class Logger
{
// ... your impl as a singleton
}
void Log( const char* data )
{
Logger.getInstance().DoRealLog( data );
}
This is a fine logger interface, all the power of your singleton, limited fuss.
Is there a possible memory leak when I'm accessing the class using. What about singleton destruction?
There is a risk of double instantiation if you're lazily allocating the singleton on the heap in a multithreaded environment. This would cause surplus instances to leak.
There are somewhat similar risks if you use a static local: Link
In my opinion explicit construction when execution starts is the best option, but whether it is done in the data segment (with a static variable in a class or global variable) or the heap is very unlikely to matter in your case. If you do allocate it on the heap you should also delete it.

Should I use static data members? (C++)

Let's consider a C++ class. At the beginning of the execution I want to read a set of values from an XML file and assign them to 7 of the data members of this class. Those values do not change during the whole execution and they have to be shared by all the objects / instances of the class in question. Are static data members the most elegant way to achieve this behavior? (Of course, I do not consider global variables)
As others have mentioned, the use of static members in this case seems appropriate. Just remember that it is not foolproof; some of the issues with global data apply to static members:
You cannot control the order of initialization of your static members, so you need to make sure that no globals or other statics refer to these objects. See this C++ FAQ Question for more details and also for some tips for avoiding this problem.
If your accessing these in a multi-threaded environment you need to make sure that the members are fully initialized before you spawn any threads.
Sounds like a good use of static variables to me. You're using these more as fixed parameters than variables, and the values legitimately need to be shared.
static members would work here and are perfectly acceptable. Another option is to use a singleton pattern for the class that holds these members to ensure that they are constructed/set only once.
It is not a clean design. Static class members are global state and global state is bad.
It might not cause you trouble if this is a small- to medium-sized project and you do not have high goals for automatic testing, but since you ask: there are better ways.
A cleaner design would be to create a Factory for the class and have the Factory pass your seven variables to the class when it constructs it. It is then the Factory's responsility to ensure that all instances share the same values.
That way your class becomes testable and you have properly separated your concerns.
PS. Don't use singletons either.
sounds like an appropriate use of static class members. just don't forget that they're really global variables with a namespace and (maybe) some protection. therefore, if there's the possibility that your application could someday evolve separate 'environments' or something that would need a set of these globals for each, you'd have painted yourself into a corner.
as suggested by Rob, consider using a singleton, which is easier to turn later into some kind of managed environment variable.
At the beginning of the execution I want to read a set of values from an
XML file and assign them to 7 of the
data members of this class. Those
values do not change during the whole
execution and they have to be shared
by all the objects / instances of the
class in question.
The sentence in boldface is the kicker here. As long as that statement holds, the use of static variables is OK. How will this be enforced?
It's hard to. So, if for your use right now the statement is always true, go ahead. If you want to be same from some future developer (or you) using your classes wrong (like reading another XML file midway in the program), then do something like what Rasmus Farber says.
Yes, static datamembers are what you look for. But you have to take care for the initialization/destruction order of your static variables. There is no mechanism in C++ to ensure that your static variables are initialized before you use them across translation units. To be safe, use what looks like the singleton pattern and is well known to fix that issue. It works because:
All static objects are completely constructed after the complete construction of any xml_stuff instance.
The order of destruction of static objects in C++ is the exact opposite of the completion of their construction (when their constructor finishes execution).
Code:
class xml_stuff {
public:
xml_stuff() {
// 1. touch all members once
// => 2. they are created before used
// => 3. they are created before the first xml_stuff instance
// => 4. they will be destructed after the last xml_stuff instance is
// destructed at program exit.
get_member1();
get_member2();
get_member3();
// ...
}
// the first time their respective function is called, these
// objects will be created and references to them are returned.
static type1 & get_member1() { static type1 t; return t; }
static type2 & get_member2() { static type2 t; return t; }
static type1 & get_member3() { static type1 t; return t; }
// ... all other 7 members
};
Now, the objects returned by xml_stuff::get_memberN() are valid the whole lifetime of any xml_stuff instance, because any of those members were constructed before any xml_stuff instance. Using plain static data members, you cannot ensure that, because order of creation across translation units is left undefined in C++.
As long as you think of testability and you have another way to set the static variables besides reading in a file, plus you don't rely on the data benig unchanged for the entire execution time of the process - you should be fine.
I've found that thinking of writing tests when you design your code helps you keep the code well-factored and reusable.