0

I was wondering if there is a way in C++ to accomplish the following:

I have a base class called ResultBase and two class that are Derived from it, Variable and Expression. I have a few methods that do work on vector<ResultBase> . I want to be able to pass in vectors of Variable and Expression into these methods. I can achieve this by creating a vector<ResultBase> and using static_cast to fill it with the members from my vector of Variable/Expression. However, once the vector has run through the methods, I want to be able to get it back as the vector of Result/Expression. I'll know for sure which one I want back. static_cast won't work here as there isn't a method to reconstruct a Variable/Expression from a ResultBase, and more importantly I wouldn't have the original properties of the Variables/Expressions

The methods modify some of the properties of the ResultBase and I need those changes to be reflected in the original vectors. (i.e. ResultBase has a property called IsLive, and one of the methods will modify this property. I want this IsLive value to be reflected in the derived class used to create the ResultBase

Whats the easiest way to accomplish this?

Megatron
  • 2,871
  • 4
  • 40
  • 58

2 Answers2

5

vector<ResultBase *> should fix your slicing problem - a vector<ResultBase> will never contain classes derived from ResultBase, but rather copies that "slice off" e.g. Expression by copying the ResultBase part of it.

See What is object slicing? for a detailed explanation of slicing.

Community
  • 1
  • 1
Erik
  • 88,732
  • 13
  • 198
  • 189
  • This is of course correct, but I think the OP is aware of it: *and more importantly I wouldn't have the original properties of the Variables/Expressions*. – Jon Mar 14 '11 at 00:11
  • @Jon: Better explain too much than too little - The next guy finding an answer in search may *not* know this – Erik Mar 14 '11 at 00:11
  • Agreed. I 'm just saying that the answer may not be very useful to the OP as it stands. – Jon Mar 14 '11 at 00:13
  • 1
    @Jon: `vector` is the obvious way of solving this though - for more specialized solutions we'd need more specialized information. – Erik Mar 14 '11 at 00:14
0

One possibility is to change your functions that do work on vector<ResultBase> into function templates that do work on vector<T>, with T a template parameter. To be even more generic, perhaps the functions can operate on a pair of iterators instead of a particular container type.

You can then call them with a vector<Variable> or vector<Expression> instead of a vector<ResultBase>, as long as Variable and Expression are both proper substitutes for ResultBase, as a derived class should be.

Alternatively as Erik says you can use pointers to get polymorphic behavior with containers. For ease of memory management, a vector of smart pointers or a Boost ptr_vector is usually preferred to a vector of raw pointers.

There's no way to convert an instance of a derived class to base and then back to derived, while preserving its original value, for pretty much the same reason that it's not possible to convert from int to char and then back, preserving the original value. If all else fails, you could perhaps bodge something together where you use the modified ResultBase objects to somehow update the original Variable or Expression objects with any changes made by the functions.

Steve Jessop
  • 273,490
  • 39
  • 460
  • 699