问题
I have an abstract base class called Base
that other programmers are to write implementations for. In some other part of the application, I want to catch all implementations that have been written and construct a single instance of each. If this could be done with no additional instructions to others beyond "implement Base", that would be beautiful. However, the code I have below, requires that each implementation register itself. It also doesn't work.
#include <iostream>
#include <vector>
class Base;
std::vector<Base*>* registrationList = new std::vector<Base*>;
class Base {
public:
Base(){}
virtual void execute() = 0;
};
class ImplementationOne: public Base {
public:
ImplementationOne(){registrationList->push_back(this);}
void execute(){std::cout << "Implementation One." << std::endl;}
static int ID;
};
class ImplementationTwo: public Base {
public:
ImplementationTwo(){registrationList->push_back(this);}
void execute(){std::cout << "Implementation Two." << std::endl;}
static int ID;
};
int main(int argc, const char * argv[]){
std::cout << "Registration List size: " << registrationList->size() << std::endl;
for(auto it = registrationList->begin() ; it != registrationList->end() ; ++it){
(dynamic_cast<Base*>(*it))->execute();
}
return 0;
}
I get an output of: Registration List size: 0
, so it is clear that the implementations were never instantiated. It is probably obvious that this wouldn't happen, but I am a beginner and this is the best I could come up with. I assumed that static int ID;
would force instantiation of each implementation, which would then register themselves. I can see static
does not result in instantiation. I leave it in my code here since it shows my intent.
What can I do to get automatic instantiation of each implementation? Is it possible?
回答1:
Adding static
members does not cause an instance to be generated, it merely declares that this type has a "global" variable. You never actually defined these members though, so if you tried to use them for anything you would have had a linker error. You'll have to actually instantiate an object and register that.
One solution might be to simply require each derived type to register an instance at startup. This is actually quite easily done, as I show here. (Note I moved your global to a static local of a static function. This prevents several problems you haven't run into yet, including providing an "owner" for the global.)
Unrelated to your issue, your code has problems:
- There is almost never any reason to have a pointer to a container.
- You are deriving polymorphically from a type with no virtual destructor.
- You
dynamic_cast<Base*>
for no apperent reason. - Each of your derived classes declares but does not define a
ID
member.
回答2:
Of course the vector is empty, you never add anything to the it. The constructors of the derived classes are not called since you never create any object instances of them.
Just because you have static members doesn't mean any object instances will be created. It just guarantees that value will be the same between different instances.
You have to explicitly create instances of the classes to have the constructor being called.
来源:https://stackoverflow.com/questions/17410942/c-automatic-instantiation-of-derived-classes