Is it ok to cast a STL container from Base type to Derived type ? For example, I have two vectors. First one is in type of a Base class, second is in type of a Derive class.
class Base
{
// Code
};
class Derive : public Base
{
// Code
};
Usage
vector<Base*>* vec_base = new vector<Base*>;
// Add some Derive type data to vec_base
vector<Derive*>* vec_derive = (vector<Derive*>*)(vec_base);
// Using elements as Derive pointers. Works fine.
Is this ok ? (It works fine, but I wanted to get some comments about this). Thank you very much.
EDIT: Updating according to the answers.
Say, If I use that vector carefully, and will not use with multiple-inheritance and will not insert objects other than Derive type, is it ok ? (I guess, it is not)
And thank you very much for the answers.
This is definitely not ok, and is one of the examples of c-style casts masking errors. "It works for me" is not indicative of well defined behaviour in this instance.
If you really want to do this I'd suggest:
#include <vector>
#include <algorithm>
#include <iterator>
using namespace std;
class Base
{
// Code
virtual ~Base();
};
class Derrive : public Base
{
// Code
};
Derrive *convert(Base * in) {
// assert here?
return dynamic_cast<Derrive*>(in);
}
int main() {
vector<Base*>* vec_base = new vector<Base*>;
// Add some Derrive type data to vec_base
vector<Derrive*>* vec_derrive = new vector<Derrive*>;
transform(vec_base->begin(), vec_base->end(), back_insert_iterator<vector<Derrive*> >(*vec_derrive), convert);
}
You are doing a c-style cast, which is essentially doing a reinterpret_cast
, which tells the compiler "treat x like y from now on, and just trust me that it works". So it will definitely compile, but is a bad idea. There is no type safety here, and it may work some of the time, but will crash unpredictably at other times.
What you can do instead:
for (unsigned int i=0; i < vec_base->length(); i++)
{
Derrive* d = dynamic_cast<Derrive*> (vec_base[i]);
if (d ) {
// this element is a Derrive instance, so we can treat it like one here
}
// else, skip it, log an error, throw an exception, whatever,
// this element in the vector is not of type Derrive
}
This is not ok. Templated types with different T
s are unrelated types (even though they both say std::vector
, and using a C-style cast just lets you get away with undefined behavior.
If it seems to work for now, consider yourself unlucky that it didn't crash.
If you know that ALL the items in the vector are the derived class then just make the vector point to derived objects up front. If you don't know that, then the cast isn't safe.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With