W
werasm
shuisheng said:Dear All,
Assume there are three classes where CA has members of class CA1 and
CA2 as follows. To make the public functions of CA1 and CA2 can work on
the members a1 and a2 in a CA object, I just write all the functions
such as a1_func1(), a1_fun2(), a2_func1(), as_func2() in the CA
interface. I think this is a stupid way since if there are more
functions in CA1 and CA2, I need to repeat them all. Is there any good
way to implement it?
Simple solution would be to use the composite pattern (This looks like
it may be a candidate):
Example:
#include <vector> //or list
#include <memory> //for auto_ptr...
namespace nsa{
template <class DeleterT>
struct Deleter
{
void operator()( DeleterT*& lval )
{
delete lval;
lval = 0;
}
};
struct Leaf
{
virtual void f() = 0;
virtual ~Leaf(){ }
};
struct CA1 : public Leaf
{
void f(){ /* Some implementation */ }
};
class CA2 : public Leaf
{
void f(){ /* Some implementation */ }
};
class Composite //CA!!!
: public Leaf //Keep interface same
{
public:
typedef std::auto_ptr<std::vector<Leaf*> > LeaveT;
Composite( LeaveT leaves )
: leaves_( leaves.get() ?
leaves : LeaveT(new std::vector<Leaf*>) )
{
}
//void add( Leaf* ){ /*...*/ }
//void remove( Leaf* ){ /*...*/}
void f()
{
std::for_each( leaves_->begin(), leaves_->end(),
std::mem_fun( &Leaf::f ) );
}
~Composite()
{
std::for_each( leaves_->begin(), leaves_->end(), Deleter<Leaf>()
);
}
private:
LeaveT leaves_;
};
}//nsa
int main()
{
Composite::LeaveT leaves( new std::vector<Leaf*> );
leaves->push_back( new CA1 );
leaves->push_back( new CA2 );
Composite ca( leaves );
ca.f(); //Calls CA1.f() and CA2.f()...
}
I appreciate your help.
Hope it helps. For anybody who wants to know, the reason I'm using
auto_ptr is for ownership transferral, that leaves only require to be
created once. Some boost utility can be used to create the sequence
more elegantly than using push_backs.
Shuisheng
OP ignore question below:
Anybody have a compile time solution? Using valuelists
(boost::inherit_linearly) perhaps. I would like to see?
Regards,
Werner