I'm trying to implement a factory pattern like this.
The problem right now is that the program terminates with a segfault in the register function because the map is not initialized yet.
// initialise the registered names map
std::map<std::string, factoryMethod> SourceFactory::registeredClasses_ = { };
bool SourceFactory::Register(std::string name, factoryMethod createMethod) {
// registeredClasses_ = { }; // This prevents the segfault but does not work for obvious reasons
auto temp = std::make_pair(name.c_str(), createMethod);
std::pair<std::map<std::string, factoryMethod>::iterator, bool> registeredPair =
SourceFactory::registeredClasses_.insert(temp);
return registeredPair.second;
}
Why is it possible for Register() to be called before the initialization of the map? I tried initializing the map in the header file but then I get the linker error
multiple definition of SourceFactory::registeredClasses_
A solution would be to set a static bool isInitialized=false and then initialize the map accordingly. But I hope this can be avoided.
It's possible when Register is called from a different translation unit before the registry has been initialised.
Unfortunately, adding a static flag would not solve anything because that would not be initialised either.
A convenient solution is to add a level of indirection:
// static
std::map<std::string, factoryMethod>& SourceFactory::registry()
{
static std::map<std::string, factoryMethod> registeredClasses;
return registeredClasses;
}
bool SourceFactory::Register(const std::string& name, factoryMethod createMethod) {
auto temp = std::make_pair(name, createMethod);
return registry().insert(temp).second;
}
This is a common problem known as the static initialisation order fiasco.
Objects with static storage duration at namespace scope are constructed in-order within a translation unit, but you don't know whether those in other translation units may undergo initialisation first.
Instead of having your container at namespace scope, make it function static (perhaps returned from a new GetRegistry() function?) so that it is constructed on first use. That could be use from main, use from initialisation of another static-duration "thing" (which is presumably where your Register call is coming from), use from the moon…
This is also why the proper way to write a singleton is to have a GetInstance() function that declares (staticly!) the instance within the function's scope.
A solution would be to set a static bool isInitialized=false and then initialize the map accordingly. But I hope this can be avoided.
Nope. Not only would you then have the same problem with the isInitialized flag, but there's nothing you can "do" with that information. You can't "initialize" something other than in an initializer, and the whole problem is that the initializer hasn't been used yet. You could assign to the map, but that would have undefined behaviour because you'd be assigning to something that doesn't exist yet… and then it would be initialized later anyway!
Related
I have a C++ program with three source files:
// main.cpp
auto return_value = managed_call(int value);
// managed.cpp
#include "private_impl.hpp"
int managed_call(int arg) {
if (arg == 0)
return private_func();
else
return arg;
}
//private_impl.cpp
static some_type some_var = construct_static_object_might_blow();
int private_func() {
....
return 42;
}
My question is about the initialization of the static object in private_impl.cpp: "when does that take place?" or more specifically - is it only initialized if the private_func function is called?
Update
I actually simplified the example a bit too much; the code in question will be run as a Python extension - i.e. it is dlopen()which is the crucial init step. This SO question turned out to be spot on.
When is the static init called in C++
I suppose that you mean, when is the variable with static storage duration initialised. If the variable has static initialisation, that happens before anything else.
If the variable has dynamic initialisation, then it is initially zero initialised during the static initialisation. The exact point of dynamic initialisation is implementation defined. The variable will be initialised at some point before it - or any other variable from that translation unit (TU) - is accessed the first time, or before any function from that TU is called.
is it only initialized if the private_func function is called?
It may be initialised whether private_func is called or not. But if private_func is called, then the variable will be initialised at some point before the function call. It is unclear to me whether the initialisation can be deferred so far that it never happens.
Relevant standard quotes in this SO post.
You have no guarantee about the order that static global objects are initialized in across compilation units. See https://isocpp.org/wiki/faq/ctors#static-init-order - you do have guarantees within a translation unit though.
The best way to not get bitten by this is to not have globals (singletons) in the first place.
Non-local static variables are initialized when their compilation unit is initialized. The standard demands that a compilation unit is initialized no later than when an element from it is accessed first, so in your example construct_static_object_might_blow() will definitely be called before the first call of private_func(). The compiler may initialize private_impl.cpp's translation unit before calling main(), but this is nothing you should rely on.
A way to get by the static init, is by making a late init of the object.
Something like this
class some_class
{
public:
some_class() {} // do nothing
~some_class() {} // do nothing either
void set(some_type value) { val = value; }
some_type get() { return val; }
void shutDown { // do some cleanup }
private:
some_type val;
}
static some_class g_SomeClass ;
int main()
{
g_SomeClass.set("something");
g_SomeClass.shutDown();
return 0;
}
If your class need a proper way to shutdown, then you must do that by calling the shutdown.
Could that be a solution ?
I'm using my own REGISTER_OBJECT() macro to create a factory full of classes.
It works as expected, except for the initialization of my static std::map variable. If I don't initialize the static std::map in a .cpp file, I'll of course get a unresolved external symbol. But the problem is, I must initialize in the .cpp file that is called first at run time. Otherwise, REGISTER_OBJECT() will get called before the std::map initializer.
//std::map MUST be initialized in the .cpp file the compiler calls first.
std::map<std::string, MyFactory*> Factory::factories; //global init
REGISTER_OBJECT(MyClass);
If I place the std::map initializer in the .cpp file I prefer, REGISTER_OBJECT will be called up to a few times, the std::map will fill accordingly, but then the std::map line hits and the variable is reset.
How on earth can I make sure std::map is initialized before any calls to REGISTER_OBJECT without putting it in another .cpp file. Thanks :)
SOLUTION
//Factory.cpp
std::map<std::string, MyFactory*>* Factory::factories = NULL;
void Factory::Register(const std::string& name, MyFactory* _class)
{
if(!factories){ factories = new std::map<std::string, MyFactory*>(); }
(*factories)[name] = _class;
}
You could make your factories variable a pointer (initialized to null), and then have your REGISTER_OBJECT macro lazy instantiate it, i.e., set it to new std::map... if it's null.
This article on (essentially) merging a singleton pattern into the class kept my static variable from being created twice (https://isocpp.org/wiki/faq/ctors#static-init-order-on-first-use-members)
The basic gist is replace
class MyClass {
// static member gets initialized twice
static inline int someNumber = randomInt();
}
... with ...
class MyClass {
// singleton like pattern keeps someNumber from being initialized more than once
static inline int& someNumber() {
static int* singletonHack = randomInt();
return &singletonHack;
}
}
Then access it like this MyClass::someNumber()
I need to instantiate many objects from a class, but each one of them needs to be aware of a certain value X that is common for every object of this class, like a global parameter. This is necessary for my constructors to work properly in my objects.
Is there a way to do that without passing the value as a constructor parameter? What I wanna do is use the same variable in all objects so I don't waste RAM.
*in my real situation it's not just an X value, is a 1024-dimmension int vector.
What you want is a static member. "When a data member is declared as static, only one copy of the data is maintained for all objects of the class". e.g.
class myClass {
public:
static int x;
};
I assume you mean that you want a vector of size 1024 as the shared variable across all your classes. You could do this:
class MyClass {
static std::vector<int> s_my_vector;
}
This code would go into your header file. In your cpp file, you'd have to initialize the std::vector. However, I do not recommend this. Class static variables that require constructor calls (i.e. not primitives or POD types) have a lot of gotchas that I'm not planning to go into. I will offer a better solution however:
class MyClass {
static std::vector<int> & GetMyVector()
{
static std::vector<int> my_vector;
static bool initialized = MyVectorInit(my_vector);
return my_vector;
}
static bool MyVectorInit(std::vector<int> & v)
{
v.resize(1024);
...
}
public:
MyClass() {
std::vector<int> & v = GetMyVector();
...
}
static void EarlyVectorInit()
{
GetMyVector();
}
}
In this case, the static local variable ensures that there will only be one copy of my_vector, and you can get a reference to it by calling GetMyVector. Furthermore, the static bool initialized is guaranteed to only be created once, which means that MyVectorInit will only be called once. You can use this method in case you need to populate your vector in some non-trivial way that can't be done in the constructor.
The way I've written it, your vector will be created automatically the first time you need to use it, which is fairly convenient. If you want to manually trigger creation for some reason, call EarlyVectorInit().
I came across the following structure in a C++ library:
In myClass.h
class myClass {
public:
static myClass* Instance();
.
.
private:
static myClass* _instance;
.
.
};
and in myClass.cpp
myClass* myClass::_instance = NULL;
// followed by the all other functions..
myClass::myClass() {
.
.
}
myClass* myClass::Instance() {
if (_instance == NULL) {
.
.
}
.
.
}
So what is the use of making the _instance to be NULL pointer outside any function? And when is this line of code executed?
Thank you.
Edit:
Adding the main function. And the instance function in myClass.cpp that checks for the value of the pointer. Still don't understand when the pointer get set to NULL though.
int _tmain(int argc, T_CHAR* argv[]) {
myClass* instance = myClass::Instance();
.
.
.
return 0;
}
So what is the use of making the _instance to be NULL pointer outside any function?
Static data members usually have to be defined, in the namespace containing their class, in one source file; they are subject to the One Definition Rule, and so must have exactly one definition in any program that uses them. This is that definition.
Initialising it with NULL makes sure it's initially null, so that the Instance() function can determine whether the instance has been created yet. This isn't strictly necesssary since, like all static variables, it will be zero-initialised whether or not you explicitly provide an initialiser.
And when is this line of code executed?
During static initialisation, before any other code in the program; since it's a trivial type with a constant initialiser.
I have stumbled upon something like this once. It was something similar to singleton. The reason (as explained by the person doing it) was that he specifically wanted to initialize instance at the first getInstance() function call and he wanted to make sure that the _instance pointer will be at first initialized to NULL (and not some garbage from memory) so that the check
if (_instance == NULL)
in the function works properly.
I am not sure this is the case here, but it's possible.
myClass* myClass::_instance = NULL;
the code attempts to initialize the static member variable.
It's an initialisation, ensuring that the pointer starts life with the value NULL from the very beginning of the program.1
It gives the pointer an invalid, but recognisable and testable value before some useful pointer value is assigned to it later on during the program. This way, you can safely test the pointer to see whether it was yet given said useful value.
In this case, since you are showing a singleton, "later" means "when an instance of myClass is first requested" using some myClass::getInstancePlease() function that you have not shown.
It is more common to implement a singleton with a function-static instance, rather than a class-static pointer to some [probably dynamically-allocated] instance.
1 As an object with static storage duration, it would do so anyway; therefore, this initialisation is actually completely pointless beyond documenting programmers' intent.
Static keyword means it is being shared by all the objects that will be instantiated by the class. Hence you need to initialize it outside any function.Static states that it is a class variable shared between all the instance of the class. It is opposite to instance variables, which each instance has its own copy. To access a class variable, there are two ways. 1) a_class::static_variable 2) a_class a; a.static_variable. The initialization must go in the source file (.cpp) rather than in the header.
Because it is a static variable the compiler needs to create only one copy of it. If you don't, you get a link error. If that is in a header you will get a copy in every file that includes the header, so get multiply defined symbol errors from the linker.
Static data members are not part of objects of a given class type; they are separate objects. As a result, the declaration of a static data member is not considered a definition. The data member is declared in class scope, but definition is performed at file scope.
These are two questions about static locals that have always bothered me and I haven't found a definitive answer to:
Question 1:
struct Test
{
static inline const char* name()
{
static const char* nameValue = "Name of Test";
return nameValue;
}
};
Since the method is inline, there should be a copy of this method in each compilation unit that calls it. But, there must be only one instance of the local static variable nameValue (correct me if I am wrong). How is this achieved? We have many instances of a function generated, but all of them refer to the same static local. Does the compiler maintain a global table of static locals associated with each function by name?
Question 2:
struct Init
{
Init() {printf("init created\n");}
~Init() {printf("init destroyed\n");}
};
struct Test
{
static void func()
{
static Init init;
}
};
The static local Init object is constructed only once, on the first call of func(). How does the compiler know when is the first call to func()? Does it maintain a flag at runtime, whether this is the first call of this func?
These are really two unrelated questions.
For the first, there are various solutions. Perhaps the most frequent
are something called weak symbols. Roughly speaking, the compiler
generates an instance under a specific name in every object file that
uses the function, and the linker throws out the duplicates, and only
keeps one in the final program.
For the second, the usual solution is to generate a boolean variable
associated with the object, and tests this when the object comes into
scope.