Unhandled exception - c++ program stops on cast - c++

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?

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.

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.

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).

Related

Pass parent pointer in derived constructor

So I was doing something like this:
Base * pParentPtr
// ... pParentPtr is used
// Cast result pointer
Derived* castedResult = (Derived*)pParentPtr;
// Copy the referenced object to stack object
Derived resultExplicitCopy = Derived(*castedResult);
// run Derived class functions
resultExplicitCopy.DeviredSpecialFunction();
// Free memory allocated by factory
delete pParentPtr;
Which means that the code uses pParentPtr but at the end we need it to be converted to Derived, then call a function that belongs only to Derived and then delete the initial pointer.
Although this works, the idea is to simplify the code. I thought on creating a contructor for Derived that takes a Base* for input:
Derived::Derived(Base* basePtr)
{
// Cast result pointer
Derived* castedResult = (Derived*)basePtr;
// Copy the referenced object to stack object
Derived resultExplicitCopy = Derived(*castedResult); // This looks bad
// run Derived class functions
resultExplicitCopy.DeviredSpecialFunction();
*this = resultExplicitCopy; // ??? this seems weird and dangerous
}
Creating a Derived instance inside the constructor seems like a bad idea, also reseting the whole object before it actually exists.
So, is there a way of pasing Base's pointer to Derived's constructor and properly building it?
I'd like it to look like this:
Base * pParentPtr
// ... pParentPtr is used
// Init derived with base
derivedInstance = Derived(pParentPtr);
// Free memory allocated by factory
delete pParentPtr;
The best way to deal with this would be to take a Base* in the constructor function and then manually setting the data fields in the constructor so for example. This is because when you call a constructor it will 'return' an instantiated version of that object to your specifications:
field1=basePtr->field1
I would avoid using the cast because it is a dangerous C cast as what it is doing is saying instead of treating what this pointer points to as having a Base type treat the memory as if it had a Derived type and if the memory doesn't match up there could be problems
This code is valid only if pParentPtr points to an object of class Derived. If it's true, then you can do one of these depending on the actual use case:
Directly call castedResult->DeviredSpecialFunction().
If you don't like the -> syntax for some reason (i'm assuming you're doing hobby project or it is not a peer-reviwed code, otherwise -> is perfectly fine), then you can "transform" pointer to a reference: Derived& resultExplicitCopy = (Derived&)(*castedResult) (note the two added ampersands).
Also I agree with comments noting that you should revise your design such that:
you don't blindly assume that pParentPtr points to Derived. Maybe the code above does the check already, but then still the following point holds:
you certainly shouldn't allow the construction of Derived form pointer Base if such construction blindly assumed that a pointer points to a Derived. Usually a class may be used in a different places in program, so a class's constructor should be clear in a way that you know what objects it may accept by looking at its signature. Having a proper parameter type makes it formally correct, and formal correctness actually makes things clearer. If constructor assumes its paremeter points to Derived, it should accept a Derived*, and accepting 'Base* would be incorrect as it allows a pointer to a non-Derived` object to be passed into it by mistake. In such a case the compiler can't help you by type checking.

C++ pointer vs object

Could you please clear up a question for me regarding pointer vs object in C++. I have the below code that has a class called "person" and a list that allows for 100 objects of that class type.
class person {...}
int main {
person* mylist;
mylist = new person[100];
mylist[0].set_name("John")
// ...
}
In this code I can call a method of the class by mylist[0].set_name() meaning (by my understanding) that mylist[0] is an object (hence the . operator to call a method). The code works fine.
I have another project where the "person" class is used as a base class to derive classes "carpenter" and "welder". The derived classes simply overwrite a virtual function called salary in the base "person" class to allow for a different calculation of salary.
person* mylist[100];
mylist[0] = new carpenter;
mylist[0]->set_name("John");
This code works fine as well. My question is - why in the first code I can call the set_name method using the . (meaning mylist[0] is an object) and in the second code I have to use the -> operator (meaning mylist[0] is a pointer to the object)?
T* represents a pointer type, which represents a variable that contains a "reference" (usually a memory address) to some instance of type T. Using a real world comparison, a T* pointer stands to T like a street address stands to a building.
Pointers allow you to refer to some instance owned by some other variable, and you can use a valid, non null instance of T* to read and write on a T. In this, they are similar to another C++ concept, references (written as T&), which allow you to alias variables, but differ significantly from pointers by not being objects in their own regard.
A pointer is, in fact, an object itself, with each pointer variable having its own unique address and being thus storable and referenceable. For instance, you can have pointers to pointers (T**) and references to pointers (T*&), but not pointers to references - pointers exist, while references may not (they are usually implemented as pointers underneath though).
To reflect the this "indirect" nature of pointers, C and C++ provide you with two different operators which allow you to dereference a pointer (* and ->), and to reference a variable (&).
For instance, you may do the following:
struct A { int x; };
// ...
A a {};
A *aptr { &a }; // `&` takes the address of `a` and stores it into the `aptr` variable of type `A*`
aptr->x = 33; // `->` is equivalent here to `(*aptr).x`, a.x is now 33
A a2 {};
A **aptrptr { &aptr }; // pointer to pointer
*aptrptr = &a2; // `aptr` now points to `a2`
operator-> is basically syntactic sugar that avoids you some cumbersome expressions like (*aptr).x.
References, being basically just aliases to something else, do not need any special syntax at all, and are always converted transparently when neeeded:
int x { 33 };
int &xref { x }; // `xref` refers to `x`
xref = 12; // `x` is now 33
int y = xref; // copies `x` into `y`, no special syntax needed
Pointers are also used in the C language to access arrays, which always decay to a pointer as soon as they are referred to in expressions. This is messy and it's one of the reasons std::vector and std::array should always be used in their place when feasible.
int x[33];
x[3] = 44; // equivalent to `*(&x[0] + 3) = 44`
Finally, the "indirect" nature of pointers and references allow C++ to convert a Derived* to a Base*, given that a derived class contains a full instance of its base (it gets more complicated with multiple inheritance though).
Every class that inherits or contains from another class containing virtual methods will include a hidden pointer to a _Virtual Method Table`, a list of pointers to functions which will be used to dispatch the virtual methods to the correct implementation.
PS: in modern C++, you should rarely need raw pointers. The correct approach is to use containers such as std::vector, std::array and std::string, and special pointer-like wrappers called smart pointers (like std::unique_ptr) every time you need a pointer for some reason. These will handle the lifetime of a pointer for you, avoiding memory leaks and vastly simplifying memory handling. For the same reason, the new operator should be mostly considered as being deprecated and should not be used at all (unless in placement new expressions, are potentially dangerous if used improperly).
basically the first case works like this: you have an array of objects. To access the object fields and methods you use . operator.
In the second case you have an array of pointers to an object. Pointer is just a memory address, that points to an object of some type. In your case, this is an array of pointers to class person. By default, these pointers are invalid; you have to set them to the address of some existing object. new creates an object on the heap, and returns you an address of that object. In order to access the value behind the pointer, you have to de-reference it. The syntax is this:
some_type obj;
some_type* ptr = &obj; // get the address of the object
(*ptr).some_method(); // de-reference the pointer and call it
ptr->some_method(); // same

How do you add abstract base class unique_ptrs to a map?

I'm currently programming a game in C++. This game features a GameManager class. The GameManager class contains a map that holds pointers to game objects. I have defined a GameObject class that is an abstract class acting simply as an interface.
I have defined two classes that derive from the GameObject class: Enemy and Loot.
I want my GameManager class to contain a map of game objects, or rather, pointers to game objects. Because my GameManager owns these objects, I want the map to contain std::unique_ptr's.
However, I'm having a difficult time actually adding derived objects (e.g. Enemy and Loot) to this map.
I want my GameManager to iterate over the game objects and call the abstract methods. Essentially, my GameManager does not care whether or not something is an enemy, loot, or whatever, it just wants to be able to call the "draw" method as declared in the base class.
How would I go about adding a unique_ptr, that points to a derived class, to a map that contains unique_ptr's to the base class? My attempts so far lead to code I can't compile. I keep getting an error that states I am not allowed to dynamically cast a derived class pointer to a base class pointer.
I feel like this work fine if I was using raw pointers, but I'm intent on using smart pointers.
Code:
#include <memory>
#include <map>
class GameObject
{
public:
virtual void draw() = 0;
};
class Enemy : GameObject
{
public:
void draw() {};
};
class Loot : GameObject
{
public:
void draw() {};
};
int main()
{
std::map<int, std::unique_ptr<GameObject>> my_map;
// How do I add an Enemy or Loot object unique_ptr to this map?
my_map[0] = dynamic_cast<GameObject>(std::unique_ptr<Enemy>().get()); // doesn't compile, complains about being unable to cast to abstract class
return 0;
}
The first cause of an error message is that a class type can never be used as the type for a dynamic_cast. The target type of dynamic_cast must always be either a pointer to class type (meaning the result is null if the cast fails) or a reference to class type (meaning to throw an exception if the cast fails).
So improvement #1:
my_map[0] = dynamic_cast<GameObject*>(std::unique_ptr<Enemy>().get());
But this won't work because GameObject is a private base class of Enemy. You probably meant to use public inheritance, but (when using class instead of struct) you must say so:
class Enemy : public GameObject
// ...
Next we'll find that the = within the map statement is invalid. The left side has type std::unique_ptr<GameObject>, which does not have any operator= that can take a GameObject* pointer. But it does have a reset member for setting a raw pointer:
my_map[0].reset(dynamic_cast<GameObject*>(std::unique_ptr<Enemy>().get()));
Now the statement should compile - but it's still wrong.
Before getting to why it's wrong, we can make a simplification. dynamic_cast is needed for getting a pointer to derived class from a pointer to base class, or for many other type changes within a more complicated inheritance tree. But it's not needed at all to get a pointer to base class from a pointer to derived class: this is a valid implicit conversion, since every object with a derived class type must always contain a subobject of the base class type, and there's no "failure" case. So the dynamic_cast here can just be dropped.
my_map[0].reset(std::unique_ptr<Enemy>().get());
The next problem is that std::unique_ptr<Enemy>() creates a null unique_ptr, and no Enemy object is created at all. To create an actual Enemy, we can write instead either std::unique_ptr<Enemy>(new Enemy) or std::make_unique<Enemy>().
my_map[0].reset(std::make_unique<Enemy>().get());
Still wrong, and in a slightly tricky way. Now the problem is that the created Enemy object is owned by the temporary std::unique_ptr<Enemy> object returned by make_unique. The reset tells the std::unique_ptr<GameObject> within the map that it should own a pointer to the same object. But at the end of the statement, the temporary std::unique_ptr<Enemy> gets destroyed, and it destroys the Enemy object. So the map is left with a pointer to a dead object, which is invalid to use - not what you wanted.
But the solution here is that we don't need to mess around with get() and reset() at all. There is an operator= that allows assigning an rvalue std::unique_ptr<Enemy> to a std::unique_ptr<GameObject>, and it does the right thing here. It makes use of the implicit conversion from Enemy* to GameObject*.
my_map[0] = std::make_unique<Enemy>();
(Note if you had a named std::unique_ptr<Enemy>, you would need to std::move it to allow the assignment, as in my_map[0] = std::move(enemy_ptr);. But std::move is not needed above because the result of make_unique is already an rvalue.)
Now this statement is much shorter and more legible, and will actually do what you want.
A comment also suggested the possibility
my_map.emplace(0, std::make_unique<Enemy>());
This is also valid, but there's a possibly important difference: if the map already has an object with key zero, the = version will destroy and replace the old one, but the emplace version will leave the map alone and the just-created Enemy will be destroyed instead.
dynamic_cast can only be used to convert between pointers, and references. GameObject is neither a pointer type, nor a reference type, so you cannot dynamic_cast to it.
You may have intended dynamic_cast<GameObject*> instead. however, you shouldn't dynamic_cast to a (pointer to) a base class. A pointer to derived type is implicitly convertible to the base class pointer. Use static_cast when implicit conversion is not desirable. Furthermore, that conversion is not possible either, since the cast is outside of any member function, and therefore cannot have access to the private base class.
Furthermore, you cannot assign a bare pointer to a unique pointer. To transfer ownership of a bare pointer to a unique pointer, you can use unique_ptr::reset. Howver, you should never store a pointer from unique_ptr::get into another unique pointer. Doing so will result in undefined behaviour when both unique pointers destructors attempt to destroy the same object. Luckily in this case the pointer is value initialized, and therefore null, so the mistake has technically no consequences. But did you use null pointer intentionally? I suspect not.
Inserting a unique pointer to derived object into a map of unique pointers to base is simple. Let ptr be a unique pointer to Enemy:
std::unique_ptr<Enemy> ptr = get_unique_pointer_from_somewhere();
Simply move assign the unique pointer:
my_map[0] = std::move(ptr);
Or, you could use emplace member function of the map.
Finally, destructor unique_ptr<GameObject> will have undefined behaviour if it points to a derived object. To fix, declare the destructor of GameObject virtual.

Casting from one templated container to another

I'm currently writing WinRT code, but I imagine this question applies to all C++. Upon user interaction, the framework calls one of my functions passing in a vector with generic Object^ pointers (very similar to void* for you non-WinRT folks). I already know what type of objects are in the vector and I'd like to cast the vector to that object type.
Example:
MyClass::SomeFunction(Vector<Object^>^ myList) {
// Warning: The following line doesn't work!!
Vector<SpecificType^>^ myTypedList = static_cast<Vector<SpecificType^>^>(myList);
// Here, I go on to interact with the templated vector.
...
}
The compiler doesn't allow me to use static_cast. safe_cast throws an exception. dynamic_cast doesn't throw an exception, but returns a null pointer.
Is there a way I can cast this thing, or do I literally have to create a new vector and copy all the members over (casting each from Object^ to SpecificType^ on insertion)?
You cannot cast Vector<Object^> to any other Vector<> because there is no inheritance involved between them. The only thing that you can do is cast each element into the right class. So, if you want a Vector<SpecificType^> you do indeed need to create it anew. Not that it is too hard:
Vector<SpecificType^> specificList;
for (Object^ p : myList)
specificList.push_back(static_cast<SpecificType^>(p));

Casting from any

I'm packing some classes into ptr_map with any typed value.
class EventManager
{
ptr_map<string, any> mSomeMap;
public:
typedef signals2::signal<void (int someSignature)> KeyEvent;
EventManager()
{
mSomeMap["KeyPressed"] = new any(new KeyEvent());
}
};
Now I want to restore my signal object from any. Here is a special function for this:
template<typename EventType>
EventType *get(const string &signalName)
{
try {
return any_cast<EventType*>(mSomeMap[signalName]);
} catch(bad_any_cast &e){}
}
As you could remember, the boost's signals are noncopyable so I can store only pointers and my function should return pointers too.
Now sample usage:
evManager.get<EventManager::KeyEvent>("KeyPressed");
Here I get segfault. I checked the types of each objects in the get function:
typeid(EventType).name()
→ N5boost8signals26signalIFvRN2sf5Event8KeyEventEENS0_19optional_last_valueIvEEiSt4lessIiENS_8functionIS6_EENSB_IFvRKNS0_10connectionES5_EEENS0_5mutexEEE
mSignalAssociation[signalName].type().name()
→ N10__cxxabiv119__pointer_type_infoE
What's wrong is there? The segfault at line with casting. Any object should consist of inserted type or not? Why it doesn't want to cast.
ptr_map<string, any> mSomeMap;
...
mSomeMap["KeyPressed"] = new any(new KeyEvent());
Do you realize what happens here? First, you create a KeyEvent object dynamically which results in a pointer. Then this pointer is wrapped into an any-object which is also dynamically created which also returns a pointer which is then again wrapped in another any object implicitly by the assignment.
Also, for extracting the right value from an any object you need to know the exact type. So, for example, if you pack a Derived-pointer into an any object, you won't be able to access it via an any_cast<Base*> because Base* and Derived* are different types in terms of the std::type_info objects boost::any uses to keep track of types. boost::any just doesn't know how to convert the packed Derived-pointer to your Base-pointer.
Is there a special reason why you wrap so many things in any-objects including pointers to any-objects? Wouldn't it make sense to use something like a ptr_map<KeyType,BaseType>? You know that if you pack a pointer into an any object that you still need to delete the pointees yourself, right? The any-object is not going to do this for you.