Technique for Using Templates and Virtual Functions - c++

A while back I learned about the Curiously Recurring Template Pattern (http://en.wikipedia.org/wiki/Curiously_recurring_template_pattern), and it reminded me of a technique I had used to implement an event queue cache.
The basic idea is that we take advantage of a Base class pointer to store a container of homogeneous pointer types. However because the Derived class is a template class, which stores an item of type T, what we are really storing is a list of heterogeneous types.
I was curious if anyone has seen this technique, which is perhaps interesting, and if so if anyone has named it? Anyone care to critique it? Is there a better way to achieve my end here?
Thanks.
#include <iostream>
#include <algorithm>
#include <functional>
#include <list>
#include <string>
class Base
{
public:
Base(){}
virtual ~Base(){}
virtual void operator()() = 0;
};
template<typename C, typename T>
class Derived : public Base
{
public:
Derived(C* c, T item) : consumer_(c), item_(item) {}
virtual void operator()()
{
consumer_->consume(item_);
}
C* consumer_;
T item_;
};
class Consumer
{
bool postpone_;
std::list<Base*> cache_;
public:
Consumer() : postpone_(true)
{
}
void pause()
{
postpone_ = true;
}
void resume()
{
postpone_ = false;
const std::list<Base*>::iterator end = cache_.end();
for ( std::list<Base*>::iterator iter = cache_.begin();
iter != end;
++iter )
{
Base* bPtr = *iter;
bPtr->operator()();
delete bPtr;
}
cache_.clear();
}
void consume(int i)
{
if ( postpone_ )
{
std::cerr << "Postpone int.\n";
cache_.push_back(new Derived<Consumer, int>(this, i));
}
else
{
std::cerr << "Got int.\n";
}
}
void consume(double d)
{
if ( postpone_ )
{
std::cerr << "Postpone double.\n";
cache_.push_back(new Derived<Consumer, double>(this, d));
}
else
{
std::cerr << "Got double.\n";
}
}
void consume(char c)
{
if ( postpone_ )
{
std::cerr << "Postpone char.\n";
cache_.push_back(new Derived<Consumer, char>(this, c));
}
else
{
std::cerr << "Got char.\n";
}
}
};
static Consumer consumer;
void destroy(Base* object)
{
delete object;
}
int main()
{
// Consumer is registered with something that sends events out to lots
// of different consumer types (think observer pattern). Also in the non-toy
// version consumer isn't being passed PODs, but various Event types.
consumer.consume(0);
consumer.consume(0.1f);
consumer.consume('x');
consumer.resume();
}
The output is:
Postpone int.
Postpone double.
Postpone char.
Got int.
Got double.
Got char.

What you are using is plain polymorphism, as Stephen points out in his comment. While you store different objects internally in the container, you are limited to using the interface defined in Base. That is, of course, unless you intend to add type checking and downcasts to actually retrieve the values. There is just a limited amount of things that you can do with unrelated objects.
Depending on what you are actually wanting to achieve you might consider using other solutions like boost::any/boost::variant if what you want is to actually store unrelated types (in the few cases where this makes sense --cells in a spreadsheet, for example).

anyone has named it?
I think it is an adapter pattern implemented without using inheritance from T.
Anyone care to critique it?
YOu could have used short template function instead of this class. Or you could use template function that returns template class. Template function can automatically guess required types - sou you could omit <> and do less typing.

Nice.
You're utilizing compiler's power to generate templated series of derived classes and it's actually cool that you can mix plain derived classes
(written by yourself) with template-specialized derived classes and with compiler-generated ones
(built as result of template instantiation).
class Base { ... };
template <typename Y> class Derived1 : public Base { ... };
template <specialization>
class Derived1 : public Base { ... };
class Derived2 : public Base { ... };
This could be useful, but it doesn't somehow extend the polymorphism term, because you're still limited to the Base class interface.
Also, you could write a plain factory which would have some templated method for generating subclasses and use it to avoid writing new Derived1<std::string>..., but write something like
std::string a;
Base* base = Factory.Create(a)

Related

C++ Polymorphism + template member function for selecting return type. How to do it?

I want to implement a class hierarchy for object dispatching. Different classes dispatch different elements, and each class can dispatch its element represented as different data types.
It is better understood through a (faulty) example. This is what I would like to have if virtual function templating was allowed:
class Dispatcher {
template <class ReturnType>
virtual ReturnType getStuffAs();
};
So that I can implement subclasses as:
class CakeDispatcher : public Dispatcher {
template <>
virtual Recipe getStuffAs(){ ... }
template <>
virtual Baked getStuffAs(){ ... }
};
class DonutDispatcher : public Dispatcher {
template <>
virtual Frozen getStuffAs(){ ... }
template <>
virtual Baked getStuffAs(){ ... }
}
So that I can do the following later on:
void function( Dispatcher * disp ) {
// Works for Donut and Cake, but result will be a different Baked object
Baked b = disp->getStuffAs<Baked>();
// works if disp points to a DonutDispatcher
// fails if it is a CakeDispatcher
// can be compiling/linking time error or runtime error. I don't care
Frozen f = disp->getStuffAs<Frozen>();
}
Requirements/constraints:
All possible return types are not known beforehand. That's why I "need" templates.
Each class can provide just some return types.
Classes must have a common ancestor, so that I can store objects through a pointer to parent class and invoke functions through this pointer.
EDIT: I CAN'T use C++11 features, but I CAN use boost library.
Things I've thought about, but are not a solution:
Obviously, virtual template functions
Curiously Recurring Template Pattern: breaks the condition of common ancestor
Using some kind of traits class containing the functionality of children classes, but it does not work because a non-virtual implementation in the parent class does not have access to this information
I could maybe store some typeid info in the parent class, passed by children on construction. This makes possible for the non-virtual parent dispatching method to dynamic-cast itself to the children type... but it appears to be ugly as hell, and I don't know if this can cause some kind cycle-referencing problem.
class Dispatcher {
private:
typeid(?) childType;
public:
Dispatcher(typeid childT) : childType(childT) {}
// NOT VIRTUAL
template <class ReturnType>
ReturnType getStuffAs()
{
// or something equivalent to this cast, which I doubt is a correct expression
return dynamic_cast<childType *>(this)->childGetStuffAs<ReturnType>();
}
};
Then child classes would implement childGetStuffAs functions, which are not virtual too.
I've read like 5-10 related questions, but none of the provided solutions seems to fit this problem.
Can any of you come up with a better solution?
Is there a standard pattern/technique for solving this problem?
EDIT: The real problem
In the real problem, I have physical models with properties that can be represented in multiple ways: functions, matrices, probability distributions, polynomials, and some others (for example, a non-linear system can be represented as a function but not as a a matrix, while a linear system can be transformed to both).
There are also algorithms which can use those models indistinctly, but they could require specific representations for some model features. That's the reason for the "getStuffAs" function. The whole think is a bit complicated --too much to explain it here properly--, but I can guarantee that in this context the interface is well defined: input, computation and output.
My intention was to make this possible assuming that the number of possible representations is fully defined beforehand, and making it possible to transform the products to already existing types/classes that cannot be modified.
However, i'm starting to realize that this is, indeed, not possible in a simple way --I don't want to write a library just for this problem.
#include <cstdio>
// as a type identifier
struct stuff {
virtual void foo() {}
};
template <typename T>
struct stuff_inh : stuff {
};
struct Dispatcher {
template <typename T>
T* getStuffAs() {
return (T*)((getStuffAsImpl( new stuff_inh<T>() )));
}
virtual void* getStuffAsImpl(void*) = 0;
virtual void type() {printf("type::dispatcher\n");}
};
struct Cake : public Dispatcher {
void* getStuffAsImpl(void* p) {
stuff* s = static_cast<stuff*>(p);
printf("cake impl\n");
if (dynamic_cast<stuff_inh<Cake>*>(s) == NULL) {
throw "bad cast";
}
return (void*)(new Cake());
}
virtual void type() {printf("type::Cake\n");}
};
struct Rabbit : public Dispatcher {
void* getStuffAsImpl(void* p) {
stuff* s = static_cast<stuff*>(p);
printf("rabbit impl\n");
if (dynamic_cast<stuff_inh<Rabbit>*>(s) != NULL) {
return (void*)(new Rabbit());
}
else if (dynamic_cast<stuff_inh<Cake>*>(s) != NULL) {
return (void*)(new Cake());
}
else {
throw "bad cast";
}
}
virtual void type() {printf("type::Rabbit\n");}
};
void foo(Dispatcher* d) {
d->getStuffAs<Cake>()->type();
d->getStuffAs<Rabbit>()->type();
}
int main() {
Rabbit* r = new Rabbit;
foo(r);
Cake* c = new Cake;
foo(c);
}
I an not sure about the correctness of this ugly solution, may it be helpful for you. >_<
deletion of resource is not coded for a clearer look.
My solution is a combination of recurring template and diamond inheritance.
At least it's working. :)
#include <iostream>
class Dispatcher
{
public:
template<class T>
T getStuff()
{
return T();
}
};
template<class T>
class Stuffer : public Dispatcher
{
public:
template<class TT=T>
TT getStuff(){
return reinterpret_cast<TT>(this);
}
};
class Cake{
public:
Cake(){}
void print()
{
std::cout << "Cake" << std::endl;
}
};
class Recipe
{
public:
Recipe(){}
void print()
{
std::cout << "Recipe" << std::endl;
}
};
class CakeRecipe : public Stuffer<Cake>, public Stuffer< Recipe >
{
public:
};
int main()
{
Dispatcher* cr = reinterpret_cast<Dispatcher*>(new CakeRecipe());
cr->getStuff<Cake>().print();
cr->getStuff<Recipe>().print();
getchar();
return 1;
}

How would you name this c++ design pattern

Knowing that this might be an inappropriate question (since the reply can be (will be) based only on personal, subjective opinions) I still risk asking it:
We wrote some code and came up with the following construct
#include <iostream>
#include <string>
class Generic
{
public: virtual void do_work() = 0;
};
class SomeAppDescriptor : public Generic
{
public: static std::string name() { return "SomeAppDescriptor"; }
};
template <class TGenericApp>
class CommonFunctionalities : public TGenericApp
{
public: void do_common_work() {
std::cout << "do_common_work for " << TGenericApp::name();
}
};
class RealClass : public CommonFunctionalities<SomeAppDescriptor>
{
public: virtual void do_work() {
do_common_work();
std::cout << "and doing the work" << std::endl;
}
};
int main(int argc, char const *argv[])
{
RealClass a;
a.do_work();
return 0;
}
And now we are in the documentation phase ... We need to come up with a name for the construct where CommonFunctionalities inherits from the template member ... and is using the properties of the SomeAppDescriptor which is actually the template member... If you are to name this construct, what would be an appropriate name for it?
Edit
The main idea is that there are a lot of AppDescriptor classes which read some data from configuration files (name, ip, database, etc ...), and there is a middle layer (here it is represented by CommonFunctionalities which does the work (but also at some obscure point the CommonFunctionalities objects are mapped to name() (map of string and Generic) in order to get the functionality of the do_work()), and at the end someone from somewhere is calling the do_work of a Generic which is implemented in a set of "upper" layer classes (RealClass)
This looks, to me, like a botched attempt at a Decorator.
SomeAppDescriptor and CommonFunctionalities do not override do_work, so they need not inherit from Generic; however the use of do_common_work suggests that might have been useful.
if RealClass inherits from Generic directly, then it can take CommonFunctionalities by composition.
Using the Decorator pattern, I would end up with:
class Generic { public: virtual void do_work() = 0; };
template <typename App>
class CommonFunctionalities: public Generic {
public:
virtual void do_work() override {
std::cout << "CommonFunctionalities - " << App::name() << "\n";
}
};
class RealClass: public Generic {
public:
RealClass(std::unique_ptr<Generic> p): previous(std::move(p)) {}
virtual void do_work() override {
if (previous) { previous->do_work(); }
std::cout << "RealClass\n";
}
private:
std::unique_ptr<Generic> previous;
};
int main() {
RealClass rc{std::make_unique< CommonFunctionalities<SomeAppDescriptor> >()};
Generic& g = rc;
g.do_work();
return 0;
}
The Decorator was specifically created to layer the work, without any class knowing more than the interface class so that you can at runtime choose which layers to use. Even if the runtime flexibility is not necessary, it can still be advantageous to use this approach because it reduces the dependencies: RealClass knows not of CommonFunctionalities.
Note: in C++, you can also use the Decorator approach without interfaces thanks to templates.
It's the Curiously Recurring Template Pattern.
I think it's somewhat of an upgrade to the Curiously Recurring Template Pattern.
looks nice. :)

Best way for derived classes to carry different data types in C++

What is the most elegant way to provide an interface in C++ that accepts derived class types that carry with them different data type members that then need to be retrieved later. The example below illustrates this where the Container class provides methods to "post" an Item that will be some kind of derived variant of BaseItem. Later on I want to get the derived Item back and extract its value.
The main thing I want is for the Container interface (post and receive) to stay the same in the future while allowing different "Item" derived types to be defined and "passed" through it. Would template be better for this somehow; I'd rather not use RTTI. Maybe there is some simple, elegant answer to this, but right now I'm struggling to think of it.
class ItemBase {
// common methods
};
class ItemInt : public ItemBase
{
private:
int dat;
public:
int get() { return dat; }
};
class ItemDouble : public ItemBase
{
private:
double dat;
public:
double get() { return dat; }
};
class Container {
public:
void post(int postHandle, ItemBase *e);
ItemBase* receive(int handle); // Returns the associated Item
};
int main()
{
ItemInt *ii = new IntItem(5);
Container c;
c.post(1, ii);
ItemInt *jj = c.receive(1);
int val = jj->get(); // want the value 5 out of the IntItem
}
This is definitely a candidate for generic programming, rather than inheritance. Remember, generics (templates) are ideal when you want identical handling for different data types. Your ItemInt and ItemDouble classes violate OO design principles (the get() method returns different data types depending on what the actual subtype is). Generic programming is built for that. The only other answer would be a tagged data type, and I personally avoid those like the plague.
How about?
template<typename T>
class Item
{
private:
T dat;
public:
T get() { return dat; }
};
class Container {
public:
template<typename T>
void post(int postHandle, Item<T> *e);
template<typename T>
Item<T>* receive(int handle); // Returns the associated Item
};
int main()
{
Item<int> *ii = new Item<int>(5);
Container c;
c.post(1, ii);
Item<int> *jj = c.receive<int>(1);
int val = jj->get(); // want the value 5 out of the IntItem
}
Your Container class looks suspiciously like a std::map. It looks to me like your ItemBase class is just a different name for "Object", the universal base class, which I think is not much different from (or better than) void*. I would avoid trying to contain items of different type in a single container. If your design seems to call for doing so, I'd rethink your design.
A pure template approach doesn't work because you apparently want to have mixed types in your container. You could work with something like Boost's any although I think you need to restore the actual. What I think is called for in this case is a base class exposing the type-independent and virtual methods plus a templatized derived class to hold the actual items:
class Base {
public:
virtual ~Base() {}
virtual void post() = 0;
};
template <typename T>
class Item: public Base {
public:
Item(T const& value): value_(value) {}
void post() { std::cout << "posting " << this->value_ << "\n"; }
private:
T value_;
};
This approach avoids the need to write any derived Item class for another value type. To make creation of these beast easier you probably want to create a suitable creation function as well, e.g.
template <typename T>
std::unique_ptr<Base> make_item(T const& value) {
return std::unique_ptr<Base>(new Item<T>(value));
}
A std::unique_ptr<Base> is returned to make sure that the allocated object is released (if you don't use C++2011 you can used std::auto_ptr<T> instead). This type can easily be converted to other pointer types, e.g. to a std::shared_ptr<Base> which is a better suited to be put into a container.

Enforcing correct parameter types in derived virtual function

I'm finding it difficult to describe this problem very concisely, so I've attached the code for a demonstration program.
The general idea is that we want a set of Derived classes that are forced to implement some abstract Foo() function from a Base class. Each of the derived Foo() calls must accept a different parameter as input, but all of the parameters should also be derived from a BaseInput class.
We see two possible solutions so far, neither we're very happy with:
Remove the Foo() function from the base class and reimplement it with the correct input types in each Derived class. This, however, removes the enforcement that it be implemented in the same manner in each derived class.
Do some kind of dynamic cast inside the receiving function to verify that the type received is correct. However, this does not prevent the programmer from making an error and passing the incorrect input data type. We would like the type to be passed to the Foo() function to be compile-time correct.
Is there some sort of pattern that could enforce this kind of behaviour? Is this whole idea breaking some sort of fundamental idea underlying OOP? We'd really like to hear your input on possible solutions outside of what we've come up with.
Thanks so much!
#include <iostream>
// these inputs will be sent to our Foo function below
class BaseInput {};
class Derived1Input : public BaseInput { public: int d1Custom; };
class Derived2Input : public BaseInput { public: float d2Custom; };
class Base
{
public:
virtual void Foo(BaseInput& i) = 0;
};
class Derived1 : public Base
{
public:
// we don't know what type the input is -- do we have to try to cast to what we want
// and see if it works?
virtual void Foo(BaseInput& i) { std::cout << "I don't want to cast this..." << std::endl; }
// prefer something like this, but then it's not overriding the Base implementation
//virtual void Foo(Derived1Input& i) { std::cout << "Derived1 did something with Derived1Input..." << std::endl; }
};
class Derived2 : public Base
{
public:
// we don't know what type the input is -- do we have to try to cast to what we want
// and see if it works?
virtual void Foo(BaseInput& i) { std::cout << "I don't want to cast this..." << std::endl; }
// prefer something like this, but then it's not overriding the Base implementation
//virtual void Foo(Derived2Input& i) { std::cout << "Derived2 did something with Derived2Input..." << std::endl; }
};
int main()
{
Derived1 d1; Derived1Input d1i;
Derived2 d2; Derived2Input d2i;
// set up some dummy data
d1i.d1Custom = 1;
d2i.d2Custom = 1.f;
d1.Foo(d2i); // this compiles, but is a mistake! how can we avoid this?
// Derived1::Foo() should only accept Derived1Input, but then
// we can't declare Foo() in the Base class.
return 0;
}
Since your Derived class is-a Base class, it should never tighten the base contract preconditions: if it has to behave like a Base, it should accept BaseInput allright. This is known as the Liskov Substitution Principle.
Although you can do runtime checking of your argument, you can never achieve a fully type-safe way of doing this: your compiler may be able to match the DerivedInput when it sees a Derived object (static type), but it can not know what subtype is going to be behind a Base object...
The requirements
DerivedX should take a DerivedXInput
DerivedX::Foo should be interface-equal to DerivedY::Foo
contradict: either the Foo methods are implemented in terms of the BaseInput, and thus have identical interfaces in all derived classes, or the DerivedXInput types differ, and they cannot have the same interface.
That's, in my opinion, the problem.
This problem occured to me, too, when writing tightly coupled classes that are handled in a type-unaware framework:
class Fruit {};
class FruitTree {
virtual Fruit* pick() = 0;
};
class FruitEater {
virtual void eat( Fruit* ) = 0;
};
class Banana : public Fruit {};
class BananaTree {
virtual Banana* pick() { return new Banana; }
};
class BananaEater : public FruitEater {
void eat( Fruit* f ){
assert( dynamic_cast<Banana*>(f)!=0 );
delete f;
}
};
And a framework:
struct FruitPipeLine {
FruitTree* tree;
FruitEater* eater;
void cycle(){
eater->eat( tree->pick() );
}
};
Now this proves a design that's too easily broken: there's no part in the design that aligns the trees with the eaters:
FruitPipeLine pipe = { new BananaTree, new LemonEater }; // compiles fine
pipe.cycle(); // crash, probably.
You may improve the cohesion of the design, and remove the need for virtual dispatching, by making it a template:
template<class F> class Tree {
F* pick(); // no implementation
};
template<class F> class Eater {
void eat( F* f ){ delete f; } // default implementation is possible
};
template<class F> PipeLine {
Tree<F> tree;
Eater<F> eater;
void cycle(){ eater.eat( tree.pick() ); }
};
The implementations are really template specializations:
template<> class Tree<Banana> {
Banana* pick(){ return new Banana; }
};
...
PipeLine<Banana> pipe; // can't be wrong
pipe.cycle(); // no typechecking needed.
You might be able to use a variation of the curiously recurring template pattern.
class Base {
public:
// Stuff that don't depend on the input type.
};
template <typename Input>
class Middle : public Base {
public:
virtual void Foo(Input &i) = 0;
};
class Derived1 : public Middle<Derived1Input> {
public:
virtual void Foo(Derived1Input &i) { ... }
};
class Derived2 : public Middle<Derived2Input> {
public:
virtual void Foo(Derived2Input &i) { ... }
};
This is untested, just a shot from the hip!
If you don't mind the dynamic cast, how about this:
Class BaseInput;
class Base
{
public:
void foo(BaseInput & x) { foo_dispatch(x); };
private:
virtual void foo_dispatch(BaseInput &) = 0;
};
template <typename TInput = BaseInput> // default value to enforce nothing
class FooDistpatch : public Base
{
virtual void foo_dispatch(BaseInput & x)
{
foo_impl(dynamic_cast<TInput &>(x));
}
virtual void foo_impl(TInput &) = 0;
};
class Derived1 : public FooDispatch<Der1Input>
{
virtual void foo_impl(Der1Input & x) { /* your implementation here */ }
};
That way, you've built the dynamic type checking into the intermediate class, and your clients only ever derive from FooDispatch<DerivedInput>.
What you are talking about are covariant argument types, and that is quite an uncommon feature in a language, as it breaks your contract: You promised to accept a base_input object because you inherit from base, but you want the compiler to reject all but a small subset of base_inputs...
It is much more common for programming languages to offer the opposite: contra-variant argument types, as the derived type will not only accept everything that it is bound to accept by the contract, but also other types.
At any rate, C++ does not offer contravariance in argument types either, only covariance in the return type.
C++ has a lot of dark areas, so it's hard to say any specific thing is undoable, but going from the dark areas I do know, without a cast, this cannot be done. The virtual function specified in the base class requires the argument type to remain the same in all the children.
I am sure a cast can be used in a non-painful way though, perhaps by giving the base class an Enum 'type' member that is uniquely set by the constructor of each possible child that might possibly inherit it. Foo() can then check that 'type' and determine which type it is before doing anything, and throwing an assertion if it is surprised by something unexpected. It isn't compile time, but it's the closest a compromise I can think of, while still having the benefits of requiring a Foo() be defined.
It's certainly restricted, but you can use/simulate coviarance in constructors parameters.

Pattern for delegation to sub-component

In the product I am working, one of very basic scenario is serialization of classes. Typically a class to be serialized calls serialization on its sub-component
e.g. if there is a class s.t. class
A{B;C;D;} then A.Pack will call pack
function on B,C,D.
Since there are many such classes, same pattern of code has to be duplicated over and over again.
Is it possible to encapsulate this behavior in a pattern (possibly using templates and inheritance)
The usual way of making a template do this is to use a type list:
#include <iostream>
// typelist definition
struct Empty {};
template < typename H, typename T = Empty >
struct Cons {
typedef H head;
typedef T tail;
};
// interfaces all items support
class IPack
{
public:
virtual void Pack() = 0;
};
// some packable items
class Fee : public IPack
{
public:
virtual void Pack() {
std::cout << "Packed Fee\n";
}
};
class Fi : public IPack
{
public:
virtual void Pack() {
std::cout << "Packed Fi\n";
}
};
class Fo : public IPack
{
public:
virtual void Pack() {
std::cout << "Packed Fo\n";
}
};
class Fum : public IPack
{
public:
virtual void Pack() {
std::cout << "Packed Fum\n";
}
};
// these two templates create a composite IPack from a list
// of the types of its parts
template <typename Types>
class PackList : public PackList<typename Types::tail>
{
protected:
typedef typename Types::head Item;
Item item;
public:
virtual void Pack() {
item.Pack();
PackList<typename Types::tail>::Pack();
}
};
template <>
class PackList<Empty> : public IPack
{
public:
virtual void Pack() {}
};
// FeeFiFoFum is a composite of four items
class FeeFiFoFum : public PackList<Cons<Fee,Cons<Fi,Cons<Fo,Cons<Fum> > > > >
{
};
// create a FeeFiFoFum and call pack on it, which calls pack on its parts
int main ()
{
FeeFiFoFum giant;
giant.Pack();
}
Proper implementations of composites created from type lists give you accessors for the members and so on, but this is enough to show how they works, and prints out that it packed Fee, Fi, Fo and Fum without specifying any behaviour.
One possible design that would help accomplish this is to use the Composite pattern. Your Component (to borrow from the Wikipedia drawing) is Packable, which would implement a Template Method Pack() that can do something like so:
GetChildren();
for each child:
child.Pack()
PackImpl();
PackImpl() is a pure virtual method in Packable, and all classes that inherit implement it appropriately. GetChildren() would return an STL container (possibly empty), for iteration. It can be implemented in Packable, along with a private member collection to store the child objects. Basically, you then inherit all the classes from Packable, implement PackImpl(), and you're done.
Note that this will cause issues if your inheritance hierarchy depends on the child pieces being members directly. If you've approached the problem in terms of aggregation, this should work well.
It's possible that the Visitor pattern may help.
http://en.wikipedia.org/wiki/Visitor_pattern
The idea of this is to separate the traversal logic (stepping through your objects) from the handling of each object. In this case, the per-object logic is serializing (encoding) a single object (or deserializing, of course). This should be fairly simple and minimally repetitive using normal OOP techniques.
Implementing the traversal and the Visitor-pattern specific code is annoying, but it's mostly boilerplate and should be a one-off thing.
One commenter wrote:
If you mean "is there a way I can write a template to automatically call a method on each of my member variables?", then the answer is no...
My (slightly evil) counter to that is yes, if the method is the destructor...
#include <iostream>
using namespace std;
bool Enable = false;
template <typename T>
class DS : public T {
public:
~DS() {
if (Enable) T::Serialize();
}
};
class A {
protected:
void Serialize() { cout << "A" << endl; }
};
class B {
protected:
void Serialize() { cout << "B" << endl; }
};
typedef DS<A> DSA;
typedef DS<B> DSB;
class C {
protected:
void Serialize() { cout << "C" << endl; }
private:
DSA a;
DSB b;
};
typedef DS<C> DSC;
int
main()
{
DSC c;
{
DSC c_copy = c;
Enable = true;
}
Enable = false;
}
The output is in reverse order, so to reconstruct objects you'd have to parse the serialized data and push each completed object on a stack. Composite objects would then know how many children to pop off of the stack. Or, of course, the serialization could go to an intermediate structure.
Another intriguing idea would be to use this hack once at startup (create and destroy only one special object) where the callbacks from the destructors would create a data structure that described the original object.
I also note that implicit copy constructors have potential for similar abuse, and possible in forward order...