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.