I have a type of "PC" (i.e. personal computer) that I need to model in C++ (can use language standards as new as C++11
, but no newer than that). In short, we have a lot of granularity for components in the PC (in my actual tool, it would be about 10 times the number of components shown here), i.e:
Tower
Motherboard
CPU
CORE1
CORE2
CORE3
CORE4
RAM_BANK
DIMM1
DIMM2
DIMM3
DIMM4
SATA_Controller
Drive1
Drive2
Drive3
PCIE_BUS
VideoCard1
VGA_OUT
HDMI_OUT
DVI_OUT
VideoCard2
VGA_OUT
HDMI_OUT
Power_Button
I would like to setup a common base class for all objects in the tree above so that I can iterate through all objects that use this common base class. Ideally, I'd like to be able to print off the inheritance tree shown above, in as clean a manner as possible. This is because I might have to support thousands of different "PCs" with different types of mothers boards, disk controllers, CPU types; some models may have components others don't have, etc.
In addition to being able to generate the tree shown above, in a generalized manner, I have some component-detection logic that needs to be implemented. For example, the motherboard
class, upon detecting a specific version of a CPU
class, will use a specific interface to communicate with that instantiation of that particular version of the CPU
class, e.g. "Mother board detected an AMD64 CPU, version/model XYZ, use this interface to talk to it". The end goal is a re-usable way to assemble virtual "PCs", and automatically assign the appropriate interface for a parent to communicate bi-directionally with a child object.
Which design pattern should I consider for such an implementation? I was thinking of a simple common base class (i.e. widget
class) which all other classes inherit. Then, the widget class has an abstract data type (list) that contains a reference/pointer to all other members in that class that also inherit from the widget
parent class. However, I can't come up with a method to auto-add all widget
-type child classes to the list. For example:
class widget {
private:
std::list<widget> children;
protected:
char name[256];
public:
void announce()
{ printf("Component name:%s.", this->name);}
};
class MotherBoard: public widget {
private:
CPU cpu1;
CPU cpu2;
RAM_bank rambank1;
public:
MotherBoard() {
// Add all classes that derive from widget to this list.
// i.e. cpu1, cpu2, rambank1.
// Also, construct `cpu1` with a generic interface that
// accepts 2 parameters: this.name (for this particular
// MotherBoard instantiation) and this->cpu1.name;
}
};
class CPU: public widget {
public:
CORE core1;
CORE core2;
CORE core3;
CORE core4;
};
class RAM_BANK: public widget {
public:
DIMM dimm1;
DIMM dimm2;
DIMM dimm3;
DIMM dimm4;
};
Finally, does C++
itself support introspection enough to be able to automatically detect all members that derive from a specific class and add them the the children
list? This is so that if a new component that inherits from widget
is added as a member to the class, people can't forget to have it included in the children
list.
Thank you.