0

I have several structs:

struct Token
{
 //some content
}

Then follows a bunch of structs that inherit from Token:
struct A : public Token{
 //Stuff
}

.
.
.
struct Z : public Token{
 //Other stuff
}

I have a vector std::vector filled with subclasses A through Z and my program crashes when I try to cast any element in the the vector to the subclass. I'm casting by doing the following:

A subclass = *((A * ) &vector[0]);

What am i doing wrong?

Grisungen
  • 333
  • 2
  • 7
  • 1
    use [`dynamic_cast`](http://en.cppreference.com/w/cpp/language/dynamic_cast) when downcasting, a [C style cast](http://en.cppreference.com/w/cpp/language/explicit_cast) is not guaranteed to be safe.. – Mgetz May 17 '14 at 12:59
  • You cannot possibly have "a vector filled with subclasses". Vectors store elements of one single, fixed type only. – Kerrek SB May 17 '14 at 13:00
  • Probably the vector stores pointers to parent class and the OP is casting the child class pointers before storing them in the vector. – Cool_Coder May 17 '14 at 13:03

3 Answers3

1

A meaningful usage would be

A &subclassref = vector[0]);

In above line, no new object is created.

BTW what is the type of your vector and what exactly do you want to achieve? If you store objects of type A to Z in a single vector, it may at some point of time suffer object slicing.

Mohit Jain
  • 30,259
  • 8
  • 73
  • 100
  • Thank you. I have a string that i convert into different tokens that all inherit from the superclass Token. I want to parse this and create objects based on the contents of the vector of tokens. – Grisungen May 17 '14 at 12:52
  • 1
    A token_container class can be prepared using [smart pointer](http://en.cppreference.com/w/cpp/memory/unique_ptr) sounds like a better solution. Smart pointer type would be token and it would contains objects of different token sub-class types. Now you can have a `std::vector` of token_container. – Mohit Jain May 17 '14 at 12:56
  • This would be more "meaningful" if the syntax were valid. – Lightness Races in Orbit May 17 '14 at 13:32
  • A solution using pointers ended up being a much better idea. Thanks for the tip! – Grisungen May 18 '14 at 09:31
1

You should use dynamic_cast when casting pointers from one type to another in your use case. The one you are using is a C style cast and I strongly suggest you to go with a dynamic_cast. So your code should look something like:

if(dynamic_cast<A *>(vector[0]))
    A subclass = *(dynamic_cast<A *>(vector[0]));

When a dynamic_cast fails it will return a NULL pointer and you should take care of it appropriately. Refer dynamic_cast and static_cast in C++ for more information. Additionally When should static_cast, dynamic_cast, const_cast and reinterpret_cast be used? will help you understand a lot more types of casts.

Community
  • 1
  • 1
Cool_Coder
  • 4,888
  • 16
  • 57
  • 99
1

This answer may be wrong because I'm making a guess as to how you have filled the std::vector<>.

You simply cannot put objects of subclasses into an std::vector<Base>. All objects in an std::vector<Base> are precisely of type Base. If you try something like this:

std::vector<Base> myVec;
myVec.push_back(Derived1(...));

you first construct an object of class Derived1 which is subsequently spliced into an object of class Base, i. e. a new object of class Base is copy-constructed from the derived object. Only this copy constructed base class object ends up in the std::vector<>.

If you want to have an std::vector<> of polymorphic objects, you must use a pointer type as the template argument (and consequently allocate the contained objects with new).

cmaster - reinstate monica
  • 38,891
  • 9
  • 62
  • 106