I am trying to write a code that keeps track of instances of my class.
Each instance is uniquely identified by a type (int). I would like to have some kind a map which links a type to a instantiation of my class.
My idea was to use a static map for this, and every instantiation registers itself when the constructor is called:
#include <unordered_map>
#include <iostream>
class Dummy {
public:
Dummy(double a, double b, double c, int type);
void GetContents() {std::cout << type_ <<": a: " << a_ << " b: " << b_ << ", c: " << c_ << std::endl;}
private:
const double a_;
const double b_;
const double c_;
const int type_;
};
static std::unordered_map<int, Dummy> Type_Map{{12, Dummy(1, 2, 3, 12)}}; // pre-defined instantiation
Dummy::Dummy(double a, double b, double c, int type) : a_(a), b_(b), c_(c), type_(type) {
Type_Map.insert({type, *this});
};
In this case, everything seems to work well:
int main()
{
Dummy(12, 6, 23, 3);
Dummy(8, 22, -4, 7);
for (auto a : Type_Map) {
std::cout << a.first << ", ";
a.second.GetContents();
}
}
which gives a correct output:
3, 3: a: 12 b: 6, c: 23
7, 7: a: 8 b: 22, c: -4
12, 12: a: 1 b: 2, c: 3
However, outside of this minimal example and in my real-life project, this seems to be unstable. While the instantiation is still registered in the map inside of the constructor, the map entry is lost as soon as I leave the constructor.
I believe this may have to do with the *this call inside the constructor where the object is not yet correctly initialized? Is this ill-defined behavior?
Is there a better concept that achieves what I want to do?
PS: What I actually need
The code is written this way because I have some instantiations of my StaticData class and many instantiations of my DynamicData class.
The content of StaticData instantiations do not change (all members are const), and there are only a few instantiations (this corresponds to the Dummy class in my minimal example).
However, there are a lot of DynamicData instantiations. For every DynamicData instantiation, there is a specific StaticData object which belongs to it.
I want to avoid that every DynamicData object has to carry a StaticData object. Therefore, it only carries an id that links it uniquely to a StaticData object.
If the user wants to find out which StaticData belongs to my specific DynamicData object, we can just look in the map (this will not happen regularly during runtime, but we still need to keep the information).
The obvious solution would be to just use pointers.
However, I want the user to be able to just initialize a DynamicData object with the id instead of having to pass a pointer to a StaticData object.