Skip to main content
GameDev.net gamedev.net
🔒 Locked

C++: dynamic class casting inside containers?

Started by Roots Jun 27, 2007 at 6:01 PM 5 replies 700+ views
Original Post
Roots
Roots
Its a bit difficult to explain what I would like to ask, so here's an example.

class Base {}; // Base is an abstract class
class A : public Base {};
class B : public Base {};
class C : public Base {};
class D : public Base {};

vector<A*> va;
vector<B*> vb;
vector<C*> vc;
vector<D*> vd;

void Foo(vector<Base*>& v) {}

int main() {
	// These calls to Foo won't compile =(
	Foo(va);
	Foo(vb);
	Foo(vc);
	Foo(vd);

	return 0;
}
So what it seems I need to do to get this to compile is to cast va/vb/vc/vd to type vector and pass that to Foo(). But I'm not sure if this is even possible (or advised), and doing a quick test doesn't seem like it is. Does anyone have any good suggestions for how to solve this problem? Note that I do *not* want to create a separate class for representing the vectors which contain Base/A/B/C/D and pass that to Foo (I know it would solve the problem, but it would screw up the design of some other parts of my code that uses these vectors).
Palidine
Palidine
Those containers are templates. When you compile a template with different item types you are essentially compiling a completely different class.

Basically think of the containers like this:

class ContainerA{    A *list;}class ContainerB{    B *list;}


There is no common base class between ContainerA and ContainerB. Similarly there can be no common base class between std::vector and std::vector.

You can just change your Foo method to operate on Base():

void Foo( Base* ){}//then call itstd::vector<A*> va::iterator ite = va.end();for( std::vector<A*> va::iterator it = va.begin(); it != ite; ++it ){    Foo( *it );}}


That's a little icky, but your architecture is perhaps to blame. It's hard to suggest alternate architectures without more context of your application and what's stored in those lists, or why they are all in different lists.

-me
Zao
Zao
A vector is a completely unrelated type to a vector.
To make it is hell. To fail is divine.
Roots
Roots
Yeah, that makes sense now. It wouldn't make sense in this case to pass it Base* pointers because what what Foo actually does is iterate through the vector and saves the relevant contents of the class object to a file. I don't think there's any efficient solution for what I'm trying to do.


Its okay though because there's only one instance where I need to do this. I just saw that my function did exactly the same for loop operation on eight different vectors and thought that there should be a cleaner way, but I guess there isn't. Thanks!
Glak
Glak
make your Foo function a template function. It is that simple.
Antheus
Antheus
Quote:
Original post by Glak
make your Foo function a template function. It is that simple.


template < class T >void Foo(vector<T*>& v) {}


Roots
Roots
Ahah, why didn't I think of that? Thanks, that should do it. I knew there was an easy solution that I was over looking. [grin]

Topic Locked

This topic has been locked by a moderator. New replies are not allowed.

Sign in to reply to this topic.