Data dispatching using dynamic_cast. How to avoid it?

Discussion in 'C++' started by D. Susman, Mar 13, 2008.

  1. D. Susman

    D. Susman Guest

    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.
     
    D. Susman, Mar 13, 2008
    #1
    1. Advertising

  2. On 2008-03-13 16:45, D. Susman wrote:
    > 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.

    --
    Erik Wikström
     
    Erik Wikström, Mar 13, 2008
    #2
    1. Advertising

  3. D. Susman

    D. Susman Guest

    On Mar 13, 7:11 pm, Erik Wikström <> wrote:
    > On 2008-03-13 16:45, D. Susman wrote:
    >
    > > 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.
    >
    > --
    > Erik Wikström


    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)
     
    D. Susman, Mar 14, 2008
    #3
  4. * D. Susman:
    > On Mar 13, 7:11 pm, Erik Wikström <> wrote:
    >> On 2008-03-13 16:45, D. Susman wrote:
    >>
    >>> 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.
    >>
    >> --
    >> Erik Wikström

    >
    > 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

    --
    A: Because it messes up the order in which people normally read text.
    Q: Why is it such a bad thing?
    A: Top-posting.
    Q: What is the most annoying thing on usenet and in e-mail?
     
    Alf P. Steinbach, Mar 14, 2008
    #4
  5. D. Susman

    Paavo Helde Guest

    "D. Susman" <> wrote in news:496bf8bd-7d68-4337-
    :

    > On Mar 13, 7:11 pm, Erik Wikström <> wrote:
    >> On 2008-03-13 16:45, D. Susman wrote:
    >>
    >> > 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.
    >>
    >> --
    >> Erik Wikström

    >
    > 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
     
    Paavo Helde, Mar 17, 2008
    #5
    1. Advertising

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

It takes just 2 minutes to sign up (and it's free!). Just click the sign up button to choose a username and then you can ask your own questions on the forum.
Similar Threads
  1. Mark
    Replies:
    4
    Views:
    2,949
    scoude
    Jan 12, 2011
  2. Alexander Malkis
    Replies:
    8
    Views:
    527
    Alexander Malkis
    Apr 14, 2004
  3. Roger23
    Replies:
    2
    Views:
    1,010
    Roger23
    Oct 12, 2006
  4. sapsi
    Replies:
    0
    Views:
    343
    sapsi
    Jun 26, 2007
  5. aaragon
    Replies:
    4
    Views:
    307
    aaragon
    Nov 22, 2007
Loading...

Share This Page