I've got a pure C++ theory question, should be a pop-fly for y'all out here.
I have a library that builds a tree-form data structure from an input file. For example, it reads in a "PlanSet" which contains a number of "Plan"s, which in turn have their own components. The relevant classes look like this:
OK, now I want to use the library in an application that works on the tree. I need to capture some intermediate results in PlanSet and in Plan, so in the app I add these classes:
Now, this is ok, the PlanSetEx constructor calls the PlanSet constructor, and everything works ok with casts in the app to say that all PlanSet pointers are really PlanSetEx pointers. The problem is that the import function down in the library, which is reading the input and creating the tree, is creating PlanSets and Plans, not PlanSetExs and PlanExs. The crunch comes when I access the whatever pointer in the app, and I get back an uninitialized value because the PlanSetEx initializer isn't called when the tree is built.
Now, I know I could copy the PlanSet import function out of the library into the PlanSetEx implementation and have it call the right constructors, but that certainly is not in the spirit of inheritance as I understand it. How should I be organizing the classes so that I can replace a part of the lower level library class with the upper level app one, and the app specific stuff stays up there while the linkage and universal functionality stays in the library?
I have a library that builds a tree-form data structure from an input file. For example, it reads in a "PlanSet" which contains a number of "Plan"s, which in turn have their own components. The relevant classes look like this:
Code:
class PlanSet {
Plan* plan1;
Plan* plan2;
...
public:
PlanSet();
};
PlanSet::PlanSet() : plan1 (NULL), plan2 (NULL) {}
class Plan {...};
Plan::Plan() {}
OK, now I want to use the library in an application that works on the tree. I need to capture some intermediate results in PlanSet and in Plan, so in the app I add these classes:
Code:
class PlanSetEx : public PlanSet {
Object* whatever;
public:
PlanSetEx();
};
PlanSetEx::PlanSetEx() : whatever (NULL) {}
class PlanEx : public Plan {<other stuff>};
PlanEx::PlanEx() : <init_other_stuff> {}
Now, this is ok, the PlanSetEx constructor calls the PlanSet constructor, and everything works ok with casts in the app to say that all PlanSet pointers are really PlanSetEx pointers. The problem is that the import function down in the library, which is reading the input and creating the tree, is creating PlanSets and Plans, not PlanSetExs and PlanExs. The crunch comes when I access the whatever pointer in the app, and I get back an uninitialized value because the PlanSetEx initializer isn't called when the tree is built.
Now, I know I could copy the PlanSet import function out of the library into the PlanSetEx implementation and have it call the right constructors, but that certainly is not in the spirit of inheritance as I understand it. How should I be organizing the classes so that I can replace a part of the lower level library class with the upper level app one, and the app specific stuff stays up there while the linkage and universal functionality stays in the library?