most elegant solution - empty virtual funciton, rtti or static data member?

Discussion in 'C++' started by Mark Turney, Jun 3, 2004.

  1. Mark Turney

    Mark Turney Guest

    Problem:
    I have a vector full of two different derived class objects (class B
    and class C) that are derived from the same base class A. I want to
    loop through vector and invoke a member function in only objects of
    class B and skip over the objects of class C. To complicate things,
    I'm using the vector position (index) as an argument in the invoked
    member function. It is possible to move the position into the object
    by adding a data member, but that feels like duplicating data when I'm
    trying to keep things streamlined. I also think that needing to use
    the vector index pretty much kills sorting or other use of iterators
    or separate vectors.

    The possible solutions that I have thought of are:
    1. Calling a common virtual function of each object through a base
    class pointer, while leaving the virtual function for class C (the
    objects to skip) empty. Cons - Empty member functions seem ugly.
    2. Using run-time type identification (typeid() == typid()) and a
    series of if () else statments to skip the objects of class C. Cons -
    The ensuing if-else tree feels like a botched switch statement.
    3. Creating a static data member in each class that holds an int that
    corresponds to the class type. Then, using this value in a switch
    statement to skip over the objects of class C. Cons - I like the
    switch in this step as opposed to solution 2, but it feels wrong
    duplicating type information.

    Am I missing something obvious, or if I'm moving in the right
    direction, which of the solutions is the most elegant? If you're
    feeling especially generous I would love to be told why any of my
    ideas suck and why the best idea is the best.

    Thanks for any help,
    -Mark
    Mark Turney, Jun 3, 2004
    #1
    1. Advertising

  2. Re: most elegant solution - empty virtual funciton, rtti or staticdata member?

    Mark Turney wrote:
    > Problem:
    > I have a vector full of two different derived class objects (class B
    > and class C) that are derived from the same base class A. I want to
    > loop through vector and invoke a member function in only objects of
    > class B and skip over the objects of class C. To complicate things,
    > I'm using the vector position (index) as an argument in the invoked
    > member function. It is possible to move the position into the object
    > by adding a data member, but that feels like duplicating data when I'm
    > trying to keep things streamlined. I also think that needing to use
    > the vector index pretty much kills sorting or other use of iterators
    > or separate vectors.
    >
    > The possible solutions that I have thought of are:
    > 1. Calling a common virtual function of each object through a base
    > class pointer, while leaving the virtual function for class C (the
    > objects to skip) empty. Cons - Empty member functions seem ugly.


    Get over it. Your class A should have that function empty and not
    pure. Class B will redefine it by overriding. Class C won't.

    > 2. Using run-time type identification (typeid() == typid()) and a
    > series of if () else statments to skip the objects of class C. Cons -
    > The ensuing if-else tree feels like a botched switch statement.


    That's definitely true.

    > 3. Creating a static data member in each class that holds an int that
    > corresponds to the class type. Then, using this value in a switch
    > statement to skip over the objects of class C. Cons - I like the
    > switch in this step as opposed to solution 2, but it feels wrong
    > duplicating type information.


    Not only that, but then what if you add class 'D' to the mix? Now
    you have to remember to implement that nonsense in it as well.

    > Am I missing something obvious, or if I'm moving in the right
    > direction, which of the solutions is the most elegant? If you're
    > feeling especially generous I would love to be told why any of my
    > ideas suck and why the best idea is the best.


    Since you imply polymorphism when you store pointers to objects
    of two different types in the same container, you should stick to
    your convictions and use polymorphism wherever possible. Going
    off and re-implementing RTTI by whatever means may be tempting,
    but trust me, it's not a good idea.

    Victor
    Victor Bazarov, Jun 3, 2004
    #2
    1. Advertising

  3. Uzytkownik "Victor Bazarov" <> napisal w wiadomosci
    news:RpHvc.912$...
    > Mark Turney wrote:
    > > Problem:
    > > I have a vector full of two different derived class objects (class B
    > > and class C) that are derived from the same base class A. I want to
    > > loop through vector and invoke a member function in only objects of
    > > class B and skip over the objects of class C. To complicate things,
    > > I'm using the vector position (index) as an argument in the invoked
    > > member function. It is possible to move the position into the object
    > > by adding a data member, but that feels like duplicating data when I'm
    > > trying to keep things streamlined. I also think that needing to use
    > > the vector index pretty much kills sorting or other use of iterators
    > > or separate vectors.
    > >
    > > The possible solutions that I have thought of are:
    > > 1. Calling a common virtual function of each object through a base
    > > class pointer, while leaving the virtual function for class C (the
    > > objects to skip) empty. Cons - Empty member functions seem ugly.

    >
    > Get over it. Your class A should have that function empty and not
    > pure. Class B will redefine it by overriding. Class C won't.
    >
    > > 2. Using run-time type identification (typeid() == typid()) and a
    > > series of if () else statments to skip the objects of class C. Cons -
    > > The ensuing if-else tree feels like a botched switch statement.

    >
    > That's definitely true.
    >
    > > 3. Creating a static data member in each class that holds an int that
    > > corresponds to the class type. Then, using this value in a switch
    > > statement to skip over the objects of class C. Cons - I like the
    > > switch in this step as opposed to solution 2, but it feels wrong
    > > duplicating type information.

    >
    > Not only that, but then what if you add class 'D' to the mix? Now
    > you have to remember to implement that nonsense in it as well.
    >
    > > Am I missing something obvious, or if I'm moving in the right
    > > direction, which of the solutions is the most elegant? If you're
    > > feeling especially generous I would love to be told why any of my
    > > ideas suck and why the best idea is the best.

    >
    > Since you imply polymorphism when you store pointers to objects
    > of two different types in the same container, you should stick to
    > your convictions and use polymorphism wherever possible. Going
    > off and re-implementing RTTI by whatever means may be tempting,
    > but trust me, it's not a good idea.
    >


    If your hierarchy has only 2 "types" of classes, ones that should be checked
    and ones that should not, you could consider having 2 vectors that store
    them separately. If possible, it's always better to use compile-time
    facilities than runtime.

    Best regards,
    Marcin
    Marcin Kalicinski, Jun 3, 2004
    #3
  4. Mark Turney

    Kevin Saff Guest

    "Mark Turney" <> wrote in message
    news:...
    > Problem:
    > I have a vector full of two different derived class objects (class B
    > and class C) that are derived from the same base class A. I want to
    > loop through vector and invoke a member function in only objects of
    > class B and skip over the objects of class C. To complicate things,
    > I'm using the vector position (index) as an argument in the invoked
    > member function. It is possible to move the position into the object
    > by adding a data member, but that feels like duplicating data when I'm
    > trying to keep things streamlined. I also think that needing to use
    > the vector index pretty much kills sorting or other use of iterators
    > or separate vectors.


    I think the solution to the indexing problem depends on what the index means
    in your problem. I don't see why you can't use iterators, though; I
    sometimes use a separate unsigned variable that I increment as I loop
    through a container. If you know you are using a vector, then you can use
    pointer arithmetic, getting the index by subtracting the begin iterator from
    your current position.

    > The possible solutions that I have thought of are:
    > 1. Calling a common virtual function of each object through a base
    > class pointer, while leaving the virtual function for class C (the
    > objects to skip) empty. Cons - Empty member functions seem ugly.


    Why do you think this is ugly? It's the standard OO solution to this
    problem. If you start seeing that class C has frequent exceptions like
    this, you might reconsider the choice to derive from A, since it cannot
    support the full interface. However, if it's an operation that makes sense
    to ignore, I don't see the problem. (In fact, if it's a function you expect
    only certain derived classes to handle, you could make the implementation
    empty in A and it won't even show up in C.)

    > 2. Using run-time type identification (typeid() == typid()) and a
    > series of if () else statments to skip the objects of class C. Cons -
    > The ensuing if-else tree feels like a botched switch statement.


    It's worse than a botched switch statement, you're doing your own virtual
    lookup instead of using the language's built in lookup. Think of it this
    way: when a virtual function is called, the program (somehow) decides what
    derived function to call from the class's type. Why do you suppose doing
    this manually is better than using the built-in feature? Surely, if the
    compiler is worth using, it will solve this problem more optimally than you
    can. The goal of OO languages was to eliminate this kind of manual type
    dispatching.

    > 3. Creating a static data member in each class that holds an int that
    > corresponds to the class type. Then, using this value in a switch
    > statement to skip over the objects of class C. Cons - I like the
    > switch in this step as opposed to solution 2, but it feels wrong
    > duplicating type information.


    This has the cons of #2 with some new ones. Notice solutions like this
    usually need both a static member of each class to identify the class, and a
    virtual function to identify the run-time object. They will need different
    names, since C++ doesn't allow virtual and static functions to share a name.
    So, this solution requires 3 functions, two of which aren't really related
    to the problem at hand; this can contribute to
    documentation/understandability issues later on.

    > Am I missing something obvious, or if I'm moving in the right
    > direction, which of the solutions is the most elegant? If you're
    > feeling especially generous I would love to be told why any of my
    > ideas suck and why the best idea is the best.


    #1 is the best. I hope I have explained why.

    > Thanks for any help,
    > -Mark


    HTH
    --
    +---- Kevin C. Saff ----+ F-15 | |Eagle
    | Engineer, Boeing, StL | _____|_^_|_____
    | Tracking/Fleet Support| * + [_(x)_] + *
    Kevin Saff, Jun 3, 2004
    #4
    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. mathieu
    Replies:
    13
    Views:
    809
    terminator
    Nov 10, 2007
  2. mathieu
    Replies:
    2
    Views:
    554
    mathieu
    Nov 8, 2007
  3. dolphin
    Replies:
    3
    Views:
    1,342
    Pete Becker
    Dec 5, 2007
  4. Anonimo
    Replies:
    0
    Views:
    292
    Anonimo
    Nov 18, 2009
  5. Grey

    Use label and ViewState with data binding funciton

    Grey, Jan 14, 2004, in forum: ASP .Net Building Controls
    Replies:
    0
    Views:
    122
Loading...

Share This Page