Reputation: 485
I want to register all of the objects of a given class so that later I can have static methods that iterate through them. I came up with the solution below. The idea is that I will supply this class to other people working with me and they will derive the class to design their own modules. However, I had to initialize the pointer array to a large size since I don't know exactly how many of this objects will be created. Is there any way to find out at compile time the number of objects created if they all are declared statically?
class Module {
static Module* module_list[];
static int count;
public:
Module(string str){
id = count;
name = str;
module_list[count++] = this;
}
static void printModules(){
for(int i = 0; i < count; i++)
cout << module_list[i]->name << endl;
}
int id;
string name;
};
Module* Module::module_list[256];
int Module::count = 0;
Module x("module x"), y("module y");
int main(){
Module::printModules();
}
Note: my original objective was to create the list itself at compile time, however, I don't have the faintest idea how to do this. Suggestions are welcome.
Upvotes: 1
Views: 372
Reputation: 1978
To access all instances of a struct defined as function statics in multiple compilation units at process start, include a magic number in the struct definition. Then, at process start, scan the loaded executable to locate the magic numbers. From each magic number address, determine the start address of the corresponding struct. To reduce the risk of false positives, place all the structs in their own linker section, and scan only that section. There can be a slight wrinkle with g++ where this causes a compile error for a few definitions. I never worked out what caused that. A workaround is to use multiple linker sections, numbered sequentially. The Nth definition in a translation unit goes in the Nth linker section, so there are as many linker sections as the maximum count of definitions in a translation unit. Keep the code tidy by using the preprocessor to automate the boilerplate needed to put each definition in a linker section. If using the workaround, use the preprocessor macro __COUNTER__
as part of the section names.
Upvotes: 0
Reputation: 93384
Is there any way to find out at compile time the number of objects created if they all are declared statically?
Not really, as the objects might be instantiated in separate translation units. Even if they weren't, there is currently no way of reflecting over a particular translation unit and look for all instantiations of a particular object in C++ (unless you want to use an external parser + code generator solution).
However, I had to initialize the pointer array to a large size since I don't know exactly how many of this objects will be created.
Just use a std::vector
, so you won't need any fixed limits:
auto& getModuleList()
{
static std::vector<Module*> result;
return result;
}
class Module {
public:
Module(string str){
id = count;
name = str;
getModuleList().emplace_back(this);
}
Upvotes: 2