Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

C++: Can I cast a vector <derived_class> to a vector <base_class> during a function call?

I have a existed class and function which look like this:

Class base_class{
    ...
}

void Func(...,vector<base_class> &vec_b,...){
    // inside the function, the vector vec_b is being re-organized and re-sized
}

and I defined a derived class which looks like:

Class derived_class: public base_class{
    ...
}

Now, without changing the function Func, can I pass a vector<derived_class> into Func, ex:

void main(){
    vector <derived_class> d;
    Func(...,d,...);
}

such that the derived class d undergoes the same re-organizing and re-sizing? I know I can cast derived class to base class in a function call with no problem, but once with a vector into play, there seems to be difficulties? I can't find the answer online, so any suggestions or help is greatly appreciated. thanks.

like image 704
AlexTPF Avatar asked Feb 20 '12 17:02

AlexTPF


4 Answers

This only works if you're using pointers.

If you're not using pointers, then there is a chance for slicing to occur. Eg.

class Base {
  protected:
    int foo;
};

class Child : public Base {
    int bar;
};

The class Base contains only a single int called foo, and the class Child contains two ints, foo and bar.

Child f;
Base sliced = (Child)f;

This will slice the child, causing it to remove some of the data from the object. You will not be able to cast the parent back into the child class, not unless your using pointers.

So, if you changed your vector<> to have pointers instead of instances of the class then you can cast back and forth between parent/child.

Using something like:

vector<Base*> vec;
vec[0] = static_cast<Base*>(new Child());

...
Func(vec);
...

Would allow you to cast the members of your vector into their child classes.

like image 61
ash Avatar answered Oct 15 '22 20:10

ash


No. Even if an A is a B, a vector<A> is not a vector<B>.

To pass one in place of the other, you can pass a vector of pointers (or use a Boost ptr_vector). Alternatively, you may be able to use a template to allow passing a vector of anything that provides the right interface.

Either of these will require changing your function though -- there's essentially no way to avoid that (and still provide the functionality you want).

like image 38
Jerry Coffin Avatar answered Oct 15 '22 22:10

Jerry Coffin


No, you cannot convert between vectors of different types. However, you can achieve what you're trying to do by making Func a template. It probably won't require you to change any code in the actual function body, but it depends on what you're doing.

template<typename T>
void Func(..., vector<T> &vec_b, ...){
    // inside the function, the vector vec_b is being re-organized and re-sized
}
like image 32
Collin Dauphinee Avatar answered Oct 15 '22 21:10

Collin Dauphinee


No.

You can let Func take vector <base_class*> and let the point elements in the vector <base_class*> point to derived_class instances.

like image 21
Ade YU Avatar answered Oct 15 '22 22:10

Ade YU