Encapsulation question re. vector objects access

Hi, there:

I'm looking for a little help in creating a framework for a program I'm puttering with. I don't do a lot of object-oriented programming in C++ (or really that much in general-- I'm an AI theory person :) ), and was hoping you guys might be able to help.

I have created a vector of a base class, and have populated it with various instances of (different) derived classes. The salient structure is fairly straightforward, namely a virtual method called runMe (for example) in the base class, and its implementation in the respective derived classes.

I'm creating a program whereby a menu-type listing of the objects in this vector can be produced, but the specifics of what each object is (i.e. which derive class) can remain hidden. Thus I want something like the following:

1
2
3
4
5
6
7
...
vector<Base> things;
...

Base* thing = things[itemNum];
thing->SomeDerivedClass::runMe();
...


..and not...

1
2
3
4
5
6
7
...
vector<Base> things;
...

Derived* thing = static_cast<Derived*> (things[itemNum]);
thing->SomeDerivedClass::runMe();
...


While the code immediately above works and makes sense to me as to why it should be that way, I wonder if there is another way around this such that I could continue to hide the specifics of the derived classes?

I'm really wanting to have something where I can fill the vector (declared as type Base) with objects from derived classes in one function, and then create a very general function that simply calls the derived method based on the current object without having to cast from Base to Derived every time. Otherwise I'll end up having to write a chunk of tailored code for each vector object to perform the conversion and then call. It seems that if I were smart I should be able to find a way to maintain the flexibility I'm looking for, but I haven't yet been able to find a comparable problem on the web (though I'm sure they're out there).

(Just a bit of further background, in particular I'm trying to create a framework for my students to encapsulate the specifics... I just want them to have to design the derived classes (I'll have designed everything else), and be able to create as many as they like, without having to worry about the internals.)

Anyhow, thanks for any responses...


-z.

First of all, you need to start with:

vector<Base*> things;

Why? You have to understand that:

1. stl is value based so if you have a vector<Base>, you can only store things of size Base in that vector - what's to say that Derived has no additional members making it larger?

2. since the size of a Base* is the same size as a Derived* so you are ok with vectors of pointers. You can use sizes of things as a "sanity check" in C++ - it's analogous to multiplying out units in physics. There is no guarantee that you are right if things come out equal, but if they are not equal or what you expect, it's definitely wrong.

3. in general, when you want to use inheritance in C++, you will end up using Base& or Base*, because a Base will literally allocate space for a Base with a vtbl pointer to Base, nothing more and nothing less, whereas a reference or pointer actually may point or refer to Base or any of its derived classes through a proper vtbl pointer to the exact class - even though from the outside, it looks like a Base& or Base*.

4. be very careful with casting in C++ - if you do it, you are generally telling the compiler, I know what I am doing so you can ignore the built-in strong type system

1
2
3
4
5
6
7
vector<Base*> things;

things.push_back( new Derived1 );
things.push_back( new Derived2 );

things[0]->aVirtualFunction();    // calls aVirtualFunction() as implemented by Derived1
things[1]->aVirtualFunction();    // calls aVirtualFunction() as implemented by Derived2 


I recommend that you reread your C++ sections on subclassing and virtual functions, and also a quick review of stl, before you step in some C++ doodoo...
Last edited on
Hi, kfmfe04:

Thanks, kindly, for the reply. The missing pointer on the Vector was just me being sloppy, and then continually overlooking it. I'll do as you say and brush up (I last did OOP in C++ back in '95; and I'm used to Java with its training wheels). That's the problem with too many things on my plate... the temptation to just quickly throw something together is annoyingly strong some days. Will behave myself... ;)


-zanyt.

Topic archived. No new replies allowed.