ryf9059
ryf9059

Reputation: 739

Invalid type conversion using static_cast, what proper casting should I use?

I have a type definition of typedef vector<Object*> ObjList; I also have a function vector<BigObject*>* ObjectBox::getBigObjectList();. BigObject is inhertied from Object

What I wanted to do is to get a vector<BigObject*>* from getBigObjectList() and convert it to vector<Object*>*, which is an upward casting, and this type is defined as ObjList so I basically wanted to to conver that into a ObjList type

I tried two ways, the first is

ObjList *normalObjectList = (ObjList*) box->getBigObjectList();

This compiles and I read from this article (When should static_cast, dynamic_cast, const_cast and reinterpret_cast be used?) which says C-style casting is rarely desireable since it can be develped into a reinterpret-cast

Then I try to use static_cast, but I got an error saying Invalid type conversion

ObjList *normalObjectList = static_cast<ObjList*> (box->ClipObjectInRect());

Neither will this work

ObjList *normalObjectList = static_cast<vector<Object*>*> (box->ClipObjectInRect());

Why isn't this working? Is this because static_cast can only be used to cast a direct class (like Object itself) instead of a nested one (I'm just totally guessing here)? What should I do in this case?

Upvotes: 1

Views: 31318

Answers (3)

Dragos
Dragos

Reputation: 508

Static cast will also fail if the compiler doesn't know (or is pretending not to know) about the relationship between the types. If your inheritance isn't declared public between the two, the compiler will consider them as unrelated types and give you the same cryptic warning.

This just bit me, so thought I'd share.

Upvotes: 16

Gorpik
Gorpik

Reputation: 11038

Your reasoning has a very usual flaw; I think we all have made the same mistake sometime. You are thinking of std::vector<> as just an output container because this is how you want to use it now, but it is not.

Just imagine that the following code would compile:

vector<BigObject*>* bigVector = box->ClipObjectInRect(); // OK
ObjList* objVector = static_cast<ObjList*>(bigVector);   // Not OK; we'll now see why
objVector->push_back(new SmallObject()); // OUCH

As you can see, allowing that cast would allow you to try to put a SmallObject* in what can only contain BigObject*. This would surely result in a runtime error.

By the way: you can actually cast between arrays of related types. This is a behaviour inherited from C. And it results in runtime errors :)

Upvotes: 3

caps
caps

Reputation: 1243

I could be wrong, but I think you might need to cast each individual object in the vector. I would try overloading getBigObjectList() to return an ObjList*. So your overloaded function would look something like

ObjList* ObjectBox::getBigObjectList()
{
 vector<Object*> return_vec
 for(vector<BigObject*>::iterator itr = ObjectBox.bigObjectList.begin(); itr != ObjectBox.bigObjectList.end(); itr++)
 {
  return_vec.push_back(static_cast<Object*> (itr));
 }
 return return_vec
}

Any particular reason you're describing your vector as a list? Or using a vector instead of a list in the first place?

EDIT: Basically, what Denis said.

Upvotes: 1

Related Questions