I have a case where I have a container of pointers to a base class and some of those pointers actually point to objects of a derived class. I need to create copies of each of the objects in the container without slicing the derived "portions" of the objects off during the copying process.
A common way to do this is by implementing something like a "virtual Parent clone()" method. This requires every class in the hierarchy to implement its own clone() method using its own type. This requires that future yet-unwritten child classes implement behavior expected by the parent class, but with no way to enforce doing so. Instead, I wrote an "adapter" class that the derived classes can inherit from instead of directly inheriting from the base class. By doing this, I can enforce consistency in yet-unwritten child classes.
The adapter class (intermediate-level in the hierarchy, between parent and child) does need to have knowledge of the child class in order to call "new()" for the proper child class type. This "feels" like it somewhat violates the traditional object-oriented model by making the parent have knowledge of classes that inherit from it. However, this may be justified from a generic programming perspective. It does seem to compile and work.
I am looking for any critiques, things to watch out for, etc. Is this code 100% portable and standards-compliant? Is there a better design pattern that I could be using instead? Is this adapter useful to others for general purposes? Thanks,
Sean
#include <cstdlib>
#include <iostream>
#include <stdio.h>
//-----------------------------------------
//Don't need to forward-declare bar; just needs to be defined before first instantiation
template<typename A, typename B>
class foo
{
public:
foo()
{
printf("foo::foo() : constructed a foo.\n");
}
virtual foo<A, B>* clone()
{
printf("foo::clone() : making a clone...\n");
return new foo<A, B>;
}
virtual void DoSomething()
{
printf("foo::DoSomething() : something...\n");
}
A myA;
B myB;
};
template<typename A, typename B, typename ChildClass>
class fooAdapter : public foo<A, B>
{
public:
fooAdapter()
{
printf("fooAdapter::fooAdapter() : constructed a fooAdapter.\n");
}
foo<A, B>* clone()
//or directly take in foo<>'s complete type rather than parametric per-parameter
{
return new ChildClass( *((ChildClass*) this) );
}
};
//-----------------------------------------
class bar : public fooAdapter<int, float, bar>
{
public:
bar()
{
printf("bar::bar() : constructed a bar.\n");
}
bar(const bar& myBar)
{
printf("bar::bar(bar) : copy-constructing a bar.\n");
}
virtual void DoSomething()
{
printf("bar::DoSomething() : something.\n");
};
//don't need to include clone() in bar
};
//-----------------------------------------
int main(int argc, char *argv[])
{
printf("About to construct myBar.\n");
bar myBar;
myBar.myA = 2;
myBar.myB = 1.5;
printf("\nAbout to clone myBar to fooTest.\n");
foo<int, float>* fooTest = myBar.clone();
fooTest->DoSomething();
printf("\nAbout to construct fooTest2 from fooTest.\n");
foo<int, float>* fooTest2 = new bar( *((bar*) fooTest) );
return EXIT_SUCCESS;
}