virtual functions/generic access

Discussion in 'C++' started by Mark Foley, Jul 23, 2007.

  1. Mark Foley

    Mark Foley Guest

    I am implementing some functionality where there is a single
    base class 'A' which provides some common functionality

    There are then two classes derived from 'A', call them 'B' and 'C'.
    Both 'B' and 'C' define functions specific only to their class. Somethng
    like...


    class A
    {
    void doX();
    void doY();
    }

    class B : class A
    {
    void getInfo();
    char * getBInfo();
    }

    class C : class A
    {
    void getInfo();
    char * getCInfo();
    }


    I then have a list of objects. Some are based on 'B', some are based
    on 'C', but I would like to treat them generically.

    ob[0]->type.doX(); // always ok
    ob[0]->type.getInfo(); // always ok
    ob[0]->type.getCInfo(); // only ok if type is Class C

    I know if I make getBInfo() virtual in the base class then I can
    make the above call regardless. But then I have to provide some
    return value for it in class A.

    If I make it a pure virtual, then I need to provide an implementation
    for it in the derived class.

    Is there a way to treat a list of objects like this generically without
    having to know their
    actual type?

    It seems kludgey to have something like:

    virtual char * getBInfo() {return NULL};

    in my base class, but perhaps that's the way it's done.

    Thanks
    Mark
    Mark Foley, Jul 23, 2007
    #1
    1. Advertising

  2. Mark Foley wrote:
    > I am implementing some functionality where there is a single
    > base class 'A' which provides some common functionality
    >
    > There are then two classes derived from 'A', call them 'B' and 'C'.
    > Both 'B' and 'C' define functions specific only to their class.
    > Somethng like...
    >
    >
    > class A
    > {

    Probably

    public:

    > void doX();
    > void doY();
    > }

    ;
    >
    > class B : class A


    You mean

    class B : public A

    > {


    Most likely

    public:

    > void getInfo();
    > char * getBInfo();
    > }

    ;
    >
    > class C : class A


    You mean

    class C : public A

    > {
    > void getInfo();
    > char * getCInfo();
    > }

    ;

    >
    > I then have a list of objects. Some are based on 'B', some are based
    > on 'C', but I would like to treat them generically.
    >
    > ob[0]->type.doX(); // always ok
    > ob[0]->type.getInfo(); // always ok
    > ob[0]->type.getCInfo(); // only ok if type is Class C


    Are you claiming that that's what happens or setting forth requirements?

    >
    > I know if I make getBInfo() virtual in the base class then I can
    > make the above call regardless.


    Regardless of what? Which of the above calls is 'getBInfo()'?

    > But then I have to provide some
    > return value for it in class A.


    If you intend to make it virtual and have it in 'A', you need to give
    it the _covariant_ return value type. It can't just be "some".

    > If I make it a pure virtual, then I need to provide an implementation
    > for it in the derived class.


    Only if you intend to instantiate the derived class.

    > Is there a way to treat a list of objects like this generically
    > without having to know their
    > actual type?


    The only way to do that is to give them polymorphic behaviour (through
    virtual functions, as you already mentioned).

    > It seems kludgey to have something like:
    >
    > virtual char * getBInfo() {return NULL};
    >
    > in my base class, but perhaps that's the way it's done.


    It's _a_ way to do it. Whether it's the best way, is debatable.

    V
    --
    Please remove capital 'A's when replying by e-mail
    I do not respond to top-posted replies, please don't ask
    Victor Bazarov, Jul 23, 2007
    #2
    1. Advertising

  3. "Mark Foley" wrote in message
    >
    > I am implementing some functionality where there is a single
    > base class 'A' which provides some common functionality
    >
    > There are then two classes derived from 'A', call them 'B' and 'C'.
    > Both 'B' and 'C' define functions specific only to their class. Somethng
    > like...
    >
    >
    > class A
    > {
    > void doX();
    > void doY();
    > }
    >
    > class B : class A
    > {
    > void getInfo();
    > char * getBInfo();
    > }
    >
    > class C : class A
    > {
    > void getInfo();
    > char * getCInfo();
    > }
    >
    >
    > I then have a list of objects. Some are based on 'B', some are based
    > on 'C', but I would like to treat them generically.
    >
    > ob[0]->type.doX(); // always ok
    > ob[0]->type.getInfo(); // always ok
    > ob[0]->type.getCInfo(); // only ok if type is Class C
    >
    > I know if I make getBInfo() virtual in the base class then I can
    > make the above call regardless. But then I have to provide some
    > return value for it in class A.
    >
    > If I make it a pure virtual, then I need to provide an implementation
    > for it in the derived class.
    >
    > Is there a way to treat a list of objects like this generically without
    > having to know their
    > actual type?
    >
    > It seems kludgey to have something like:
    >
    > virtual char * getBInfo() {return NULL};
    >
    > in my base class, but perhaps that's the way it's done.
    >
    > Thanks
    > Mark


    Mark,
    Yes when you override a virtual function it must be declared as virtual in
    the base class.
    You can read more about virtual functions in
    The C++ Programming Language, 3rd. ed., par. 12.2.6
    and also on:
    http://www.parashift.com/c -faq-lite/virtual-functions.html
    Regards, Maarten.
    Maarten Kronenburg, Jul 23, 2007
    #3
  4. Mark Foley

    Jim Langston Guest

    "Mark Foley" <> wrote in message
    news:46a4dcd0$0$12163$...
    >
    > I am implementing some functionality where there is a single
    > base class 'A' which provides some common functionality
    >
    > There are then two classes derived from 'A', call them 'B' and 'C'.
    > Both 'B' and 'C' define functions specific only to their class. Somethng
    > like...
    >
    >
    > class A
    > {
    > void doX();
    > void doY();
    > }
    >
    > class B : class A
    > {
    > void getInfo();
    > char * getBInfo();
    > }
    >
    > class C : class A
    > {
    > void getInfo();
    > char * getCInfo();
    > }
    >
    >
    > I then have a list of objects. Some are based on 'B', some are based
    > on 'C', but I would like to treat them generically.
    >
    > ob[0]->type.doX(); // always ok
    > ob[0]->type.getInfo(); // always ok
    > ob[0]->type.getCInfo(); // only ok if type is Class C
    >
    > I know if I make getBInfo() virtual in the base class then I can
    > make the above call regardless. But then I have to provide some
    > return value for it in class A.
    >
    > If I make it a pure virtual, then I need to provide an implementation
    > for it in the derived class.
    >
    > Is there a way to treat a list of objects like this generically without
    > having to know their
    > actual type?
    >
    > It seems kludgey to have something like:
    >
    > virtual char * getBInfo() {return NULL};
    >
    > in my base class, but perhaps that's the way it's done.


    Using polymorphism you can ask the instance if it is type C.

    if ( dynamic_cast<C*>( ob[0] ) != NULL )
    dynamic_cast<C*>( ob[0] )->getCInfo(); // only ok if type is Class
    C
    Jim Langston, Jul 24, 2007
    #4
  5. * Mark Foley:
    > I am implementing some functionality where there is a single
    > base class 'A' which provides some common functionality
    >
    > There are then two classes derived from 'A', call them 'B' and 'C'.
    > Both 'B' and 'C' define functions specific only to their class. Somethng
    > like...
    >
    >
    > class A
    > {
    > void doX();
    > void doY();
    > }
    >
    > class B : class A
    > {
    > void getInfo();
    > char * getBInfo();
    > }
    >
    > class C : class A
    > {
    > void getInfo();
    > char * getCInfo();
    > }
    >
    >
    > I then have a list of objects. Some are based on 'B', some are based
    > on 'C', but I would like to treat them generically.
    >
    > ob[0]->type.doX(); // always ok
    > ob[0]->type.getInfo(); // always ok
    > ob[0]->type.getCInfo(); // only ok if type is Class C
    >
    > I know if I make getBInfo() virtual in the base class then I can
    > make the above call regardless. But then I have to provide some
    > return value for it in class A.
    >
    > If I make it a pure virtual, then I need to provide an implementation
    > for it in the derived class.
    >
    > Is there a way to treat a list of objects like this generically without
    > having to know their actual type?


    Yes.

    First, you should move the common functionality getInfo() up to A, as a
    virtual function.

    For functions getBInfo() and getCInfo() you can simply invert the usage
    pattern: instead of client code calling these functions on an object o,
    you let the o object call back to the client code with the necessary
    data. I.e., in class A you provide a function

    virtual void callbackOn( CallbackInterface& someObject ) = 0;

    and in class B e.g.

    virtual void callbackOn( CallbackInterface& someObject )
    {
    someObject.doStuffWith( getBInfo() );
    }

    although you should probably reconsider the use of raw pointers, and
    also the naming convention (get rid of "get" and "info"...).

    Ditto for class C.

    This is known as the visitor pattern (google).


    > It seems kludgey to have something like:
    >
    > virtual char * getBInfo() {return NULL};
    >
    > in my base class, but perhaps that's the way it's done.


    It's kludgy and not the way it's done.

    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, Jul 24, 2007
    #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. Michael Winter
    Replies:
    9
    Views:
    608
    Michael Winter
    Sep 24, 2003
  2. heted7
    Replies:
    33
    Views:
    1,020
    Chris Dearlove
    May 12, 2005
  3. Tony Johansson

    generic functions(template functions)

    Tony Johansson, Aug 16, 2005, in forum: C++
    Replies:
    3
    Views:
    399
    Srini
    Aug 16, 2005
  4. Replies:
    3
    Views:
    365
    Nitin Motgi
    Jan 31, 2006
  5. John Goche
    Replies:
    10
    Views:
    725
    Marcus Kwok
    Dec 8, 2006
Loading...

Share This Page