Data dispatching using dynamic_cast. How to avoid it?

D

D. Susman

Hi,

I am working on a data centric project. I have a Process function that
will be called by some thread. The signature goes:

void Process( Base* base )
{
}

There are hundred possibilities on what "base" actually (i.e. actual
run-time type) is. I would like to avoid the bulky if statements to
handle the downcasts. Is there a common approach/idiom to handle that?

Thank you.
 
E

Erik Wikström

Hi,

I am working on a data centric project. I have a Process function that
will be called by some thread. The signature goes:

void Process( Base* base )
{
}

There are hundred possibilities on what "base" actually (i.e. actual
run-time type) is. I would like to avoid the bulky if statements to
handle the downcasts. Is there a common approach/idiom to handle that?

You want Base to have a process() function so you can do something like
this:

void Process( Base* base )
{
base->process();
}

And then all you need to do is override the process() function in all
the base-classes.
 
D

D. Susman

You want Base to have a process() function so you can do something like
this:

void Process( Base* base )
{
base->process();
}

And then all you need to do is override the process() function in all
the base-classes.

That is not possible since Base objects have been designed as bean
classes due to the used data distribution technology, i.e. classes
holding only data & get/sets (I know this is not good OO but think of
it as a sort of legacy I have deal with)
 
A

Alf P. Steinbach

* D. Susman:
That is not possible since Base objects have been designed as bean
classes due to the used data distribution technology, i.e. classes
holding only data & get/sets (I know this is not good OO but think of
it as a sort of legacy I have deal with)

class IBase
{
public:
typedef boost::shared_ptr<IBase> Ptr;

virtual ~IBase() {}

virtual void process() = 0;
};

class SensibleA: virtual IBase
{
private:
boost::shared_ptr<BeanA> myData;

SensibleA( SensibleA const& );
SensibleA& operator=( SensibleA const& );

public:
typedef boost::shared_ptr<SensibleA> Ptr;
explicit SensibleA( BeanA* pData ): myData( pData ) {}

virtual void process() { ... }
};

IBase::ptr sensibleFrom( Base* p ) { ... }
// This function might be simplified by using a factory repository
// with factories identified by some bean class id.


void process( IBase::ptr pBean )
{
pBean->process();
}


Cheers, & hth.,

- Alf
 
P

Paavo Helde

That is not possible since Base objects have been designed as bean
classes due to the used data distribution technology, i.e. classes
holding only data & get/sets (I know this is not good OO but think of
it as a sort of legacy I have deal with)

Well, in this case you can emulate the virtual function dispatch by hand.
If each different class contains a numeric type id (this is data,
right?), starting from 0, then you can do:

void process_A(Base* base) {
A* a = static_cast<A*>(base);
// process object of type A
}

void process_B(Base* base) {
B* b = static_cast<B*>(base);
// process object of type B
}

typedef void (*process_func)(Base* obj);

static process_func func_table[] = {
&process_A,
&process_B,
// ...
};

void Process( Base* base ) {
(*func_table[base->id_])(base);
}

hth
Paavo
 

Ask a Question

Want to reply to this thread or ask your own question?

You'll need to choose a username for the site, which only take a couple of moments. After that, you can post your question and our members will help you out.

Ask a Question

Members online

No members online now.

Forum statistics

Threads
473,754
Messages
2,569,521
Members
44,995
Latest member
PinupduzSap

Latest Threads

Top