473,387 Members | 1,573 Online
Bytes | Software Development & Data Engineering Community
Post Job

Home Posts Topics Members FAQ

Join Bytes to post your question to a community of 473,387 software developers and data experts.

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

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
Jul 22 '05 #1
3 1962
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
Jul 22 '05 #2

Uzytkownik "Victor Bazarov" <v.********@comAcast.net> napisal w wiadomosci
news:Rp****************@dfw-read.news.verio.net...
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

Jul 22 '05 #3
"Mark Turney" <go****@freelance3d.com> wrote in message
news:ec**************************@posting.google.c om...
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)_] + *
Jul 22 '05 #4

This thread has been closed and replies have been disabled. Please start a new discussion.

Similar topics

9
by: Patchwork | last post by:
Hi Everyone, I have a design related question (in C++) that I am hoping someone can help me with. It is related to my previous post but since it was pointed out that I was more or less asking...
3
by: Daniel Graifer | last post by:
Why doesn't c++ support virtual data? It supports class data of type pointer to function (that's what virtual functions really are). In terms of implementation, why can't I have other types of...
6
by: Dumitru Sipos | last post by:
Hello everybody! is there possible to have a function that is both static and virtual? Dumi.
11
by: santosh | last post by:
Hello, I was going through the Marshal Cline's C++ FAQ-Lite. I have a doubt regarding section 33.10. Here he is declaring a pure virtual destructor in the base class. And again defining...
52
by: Michael Hopkins | last post by:
Hi all We all know that C++ is a cleverly conceived multi-paradigm language that sacrifices very little in efficiency for what it delivers in terms of type-safety, encapsulation and generic...
6
by: noel.hunt | last post by:
I have a base class, PadRcv, with virtual functions. User code will derive from this class and possibly supply it's own functions to override the base class virtual functions. How can I test that...
7
by: Markus Svilans | last post by:
Hello, My question involves virtual functions and inheritance. Suppose we have a class structure, that consists of "data" classes, and "processor" classes. The data classes are derived from...
23
by: Dave Rahardja | last post by:
Since C++ is missing the "interface" concept present in Java, I've been using the following pattern to simulate its behavior: class Interface0 { public: virtual void fn0() = 0; };
32
by: r.z. | last post by:
class vector3 { public: union { float data; struct { float x, y, z; };
0
by: Charles Arthur | last post by:
How do i turn on java script on a villaon, callus and itel keypad mobile phone
0
by: aa123db | last post by:
Variable and constants Use var or let for variables and const fror constants. Var foo ='bar'; Let foo ='bar';const baz ='bar'; Functions function $name$ ($parameters$) { } ...
0
by: ryjfgjl | last post by:
If we have dozens or hundreds of excel to import into the database, if we use the excel import function provided by database editors such as navicat, it will be extremely tedious and time-consuming...
0
by: ryjfgjl | last post by:
In our work, we often receive Excel tables with data in the same format. If we want to analyze these data, it can be difficult to analyze them because the data is spread across multiple Excel files...
0
BarryA
by: BarryA | last post by:
What are the essential steps and strategies outlined in the Data Structures and Algorithms (DSA) roadmap for aspiring data scientists? How can individuals effectively utilize this roadmap to progress...
1
by: nemocccc | last post by:
hello, everyone, I want to develop a software for my android phone for daily needs, any suggestions?
1
by: Sonnysonu | last post by:
This is the data of csv file 1 2 3 1 2 3 1 2 3 1 2 3 2 3 2 3 3 the lengths should be different i have to store the data by column-wise with in the specific length. suppose the i have to...
0
Oralloy
by: Oralloy | last post by:
Hello folks, I am unable to find appropriate documentation on the type promotion of bit-fields when using the generalised comparison operator "<=>". The problem is that using the GNU compilers,...
0
jinu1996
by: jinu1996 | last post by:
In today's digital age, having a compelling online presence is paramount for businesses aiming to thrive in a competitive landscape. At the heart of this digital strategy lies an intricately woven...

By using Bytes.com and it's services, you agree to our Privacy Policy and Terms of Use.

To disable or enable advertisements and analytics tracking please visit the manage ads & tracking page.