Virtual Base Classes

This is a discussion on Virtual Base Classes within the C++ Programming forums, part of the General Programming Boards category; I have a 20 year old, 100,000 line C program that I am trying to slowly convert to C++. Part ...

Virtual Base Classes

I have a 20 year old, 100,000 line C program that I am trying to slowly convert to C++. Part of the code has a virtual base class with a large number of derived classes.

Question 1: For each derived class, I want to have a function that takes a pointer to the base class and returns a boolean indicating if the pointer dereferences to that derived class. Right now I use a virtual function for every single derived class, which means that every time I add a new derived class, I have to edit every other derived class include file and put in a funtion that returns false. This can't be the right way to do this!

Question 2: Say I have a function that takes a pointer particular derived class (bob) as an argument, or is a member function of class bob. Is there an elegant way to call this function on a pointer to the base class, assuming I have already checked that the pointer is really from the correct derived class? Right now I do a cast:

You would have to add just this one virtual function to all derived classes, but it would only be the one function, not separate functions with different names for each derived class type. Also note that this will return true if the pointer points to a class derived from Derived or its children.

For question 2, if you have already checked that the pointer refers to the correct derived class, then a cast is the best way. I prefer a static_cast for this situation:

Code:

static_cast<bob*>(pointer)->function();

Note that both of these situations are often (but not always) a signal that your design could be improved. You don't usually want to know what the base class pointer pointer points to, you just want to use its interface and let the derived classes implement the interface appropriately. You might want to consider rethinking whether the derived classes really model an is-a relationship.

As far as the casts, the relationships between the classes all make good sense. The problem is 100,000 lines of C, which originally used a tagged union of structs. I hope to get rid of most of the casts someday, but one thing at a time.

>> So just to make sure I understand, I would use TestPointer like this:
Actually, that is correct. I made a mistake when I said it should be virtual, instead it should be static. You don't actually need a function, you can just use the code directly:

I agree. That many virtual casts are indicative of a design problem. It may be a design problem inherited from the C version, but the way I see it, you should ask yourself this question: if now is not the time to change the design, when is? When the C++ version is done?

I agree also. Most of my C++ coding problem are due to not knowing quite how to wrap my head around C++'s style of OOP. For example, the section I am working on now is a symbolic manipulation code, with about 10 different polymorphic types (numbers, operators, arrays, etc). The Compare() function ('==', in other words) currently accounts for ten of those dynamic casts, since it is a virtual function that looks like:

I am certain that there is some cute way to write this function without a cast; I just don't know what it is yet. A template would cut the number down from 10 to 1, but that doesn't change the underlying code any.

Actually, that is a situation I came across a few years ago and asked about on a programming forum. In this case the dynamic_cast is an appropriate and valid solution, and it is how I solved my issue as well.

If the only situations in which you are using the dynamic_cast are ones in which the functionality depends on the derived type of both operands, then you are probably ok.