I would like to be able to display different subclasses in a 'human readable' form using a common external function. Printing the 'data' in each instantiation is trivial, but I am struggling with an elegant way to print the details (meta) about the contents of each object.
I can achieve what I want by the following triple of AsData
, FieldNames
and GetFieldNames
. AsData
packages the member data in a readable form, FieldNames
stores a static list of the data field names for the class at that point in the hierarchy and GetFieldNames
wraps FieldNames
with an inheritable function:
class A {
public:
A(const string& name) { /* Setup data */ }
// ... functions to access data members go here ...
virtual const vector<string>& GetFieldNames() {
return A::FieldNames;
}
protected:
static const vector<string> FieldNames;
// ... some data members ...
};
class B : public A {
public:
B(const string& name, const string& description): A (name) { /* Setup extended data */ }
// ... functions to access additional data members go here ...
virtual const vector<string>& GetFieldNames() {
return B::FieldNames;
}
protected:
static const vector<string> FieldNames;
// ... some additional data members ...
};
So the usage could be as follows:
void PrintTable (vector<shared_ptr<A> >& objects) {
// Print the field names.
for(const string& name : objects.front()->GetFieldNames())
cout << name << "\t";
// ... code to print the actual data goes here ...
}
int main(int argc, char **argv) {
vector<shared_ptr<A> > myObjects;
myObjects.push_back(make_shared<B>("Box", "Storage container"));
myObjects.push_back(make_shared<B>("Glass", "Drink container"));
PrintTable (myObjects);
return 0;
}
I would like to ask if it is possible to override a static const member and extend it (I know that sounds like a contradiction) so I can add fields to the static const FieldNames, i.e. something like:
const vector<string> A::FieldNames = {"NAME"};
const vector<string> B::FieldNames = ClassA::FieldNames + {"DESC"}; // Obviously not possible!
I would also be happy to use static const char* const FieldsConst[]
instead of vector<string>
.
I have looked at this answer and CRTP but I don't think they fit my problem?
TIA :)