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.
I have some type hierarchy :
class GameObject{...};
class Subject:public GameObject{...};
class Player:public Subject{...};
class Bullet:public Subject{...};
class Enemy:public Subject{...};
In traversing the array of GameObject*, I check the condition and call method foo(*object1, *object2) ( object1 is reference to Bullet, object2 is reference to Player).
std::vector<GameObject*> objects;
// fill array ( pointers to Bullet, Enemy, Player)
foreach(auto obj1 : objects)
{
foreach(auto obj2 : objects)
{
if(obj1.getID() != obj2.getID()
{
foo(*obj1, *obj2);
}
}
}
Also I write some overloaded foo methods :
void foo(GameObject&, GameObject&)
void foo(Bullet&, Player&)
void foo(Bullet&, Enemy&)
But only foo(GameObject&, GameObject&) is called. Why?
These are pointers to GameObject. You dereference them and get objects of type GameObject, and this makes sense. If you dereferenced a pointer to int and got an object of type Apple, that'd be very odd.
GameObject * (a pointer to GameObject) means that there exists some piece of memory that this pointer points to, and this memory should be treated as an object of type GameObject. When you dereference a pointer, you actually get access to that memory, which is obviously treated as GameObject.
foo() overload to be called is chosen during program compilation. And compiler obviously has no idea what are the real types of objects that you pass in your loops so it chooses the only thing it knows for sure.
There are various ways to workaround this problem in general, google "double dispatch" or "visitor pattern".
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).
I have a list of smart pointers where each pointer points to a separate Entity class.
std::list<std::unique_ptr<Entity>> m_entities;
I would like the constructor to handle the assigning of each pointer to a std::list class as it is "automatically" handled by the code on class instantiation. However, if this design is bad then I would welcome a better alternative as it only makes sense to me coming from a C# background.
Entity::Entity(Game &game)
: m_game(game),
m_id(m_game.g_idGenerator->generateNewID())
{
m_game.m_entities.push_back(std::unique_ptr<Entity>(this));
}
The main problem I have encountered with this method is that the Entity class' lifetime is unmanaged by the Entity class.
For example if I allocate an Entity class on the stack it will call the Entity destructor after leaving the method in which it was allocated and the pointer will no longer be valid.
I therefore considered the alternative of creating a smart pointer, allocating the Entity class to the heap and then explicitly adding the pointer to the list.
std::unique_ptr<Entity> b(new Entity(*this));
m_entities.push_back(b); // ERROR
This produces the following error
error C2664: 'void std::list<_Ty>::push_back(_Ty &&)' : cannot convert parameter 1 from 'std::unique_ptr<_Ty>' to 'std::unique_ptr<_Ty> &&'
What would be considered the best approach for allocating each pointer to the list and is a constructor based version possible?
I'm currently thinking that it is the list of smart pointers that should handle the lifetime for each Entity class and that assigning pointers in a constructor is not a good design choice. In that case I should probably create a CreateEntity method that adds the pointer to list rather than let the constructor handle it. Is this better?
I considered what type of smart pointer would be appropriate for this operation after reading through questions found here, here and here (offsite). It is difficult to get an exact answer based on what I've read so far though as they all offer somewhat conflicting advice.
Using constructor this way is definitely not good idea because constructor has no information about how object is created and controlled - on the stack, statically, dynamically by some smart pointer, dynamically by dumb pointer?
To solve this problem you could use static factory method to create Entity instances:
class Entity
{
public:
// Variant with unique ownership
static void CreateGameEntity(Game& game)
{
std::unique_ptr<Entity> p(new Entity());
game.m_entities.push_back(std::move(p));
}
// OR (you cannot use both)
// Variant with shared ownership
static std::shared_ptr<Entity> CreateGameEntity(Game& game)
{
std::shared_ptr<Entity> p(new Entity());
game.m_entities.push_back(p);
return p;
}
private:
// Declare ctors private to avoid possibility to create Entity instances
// without CreateGameEntity() method, e.g. on stack.
Entity();
Entity(const Entity&);
};
Which smart pointer to use? Well, this depends on your design. If Game object solely owns Entity instances and completely manages their lifetime, using std::unique_ptr is OK. If you need some kind of shared ownership (e.g. you have several Game objects that can share same Entity objects) you shall use std::shared_ptr.
Also in case of unique ownership you may use Boost Pointer Container library. It contains specialized owning pointer containers like ptr_vector, ptr_list, ptr_map etc.
I won't comment on your design questions, but to fix your error, change your code to either:
m_entities.push_back(std::unique_ptr<Boundary>(new Boundary(*this, body)));
or:
std::unique_ptr<Boundary> b(new Boundary(*this, body));
m_entities.push_back(std::move(b));
The reason is that b in your code is an lvalue, but std::unique_ptr<> is a move-only type (i.e. has no copy constructor).
The problem in your code is that you try to move a std::unique_ptr<T> from an l-value. The instantiations of std::unique_ptr<T> are non-copyable and are only movable. To move from an l-value you need to explicitly do so:
this->m_entities.push_back(std::move(b));
The call to std::move() won't really move anything but it does yield a type which indicates to the compiler that the object can be moved.
To address the issue with the stack-created instance, you could simply add a parameter to the constructor that tells it to not add the new instance to the list, eg:
Entity::Entity(Game &game, bool AddToList = true)
: m_game(game),
m_id(m_game.g_idGenerator->generateNewID())
{
if (AddToList) m_game.m_entities.push_back(this);
}
.
{
...
Entity e(game, false);
...
}
Another option might be to add a destructor to Entity that removes it from the list if it is still present, but that might get a little complex trying to avoid conflicts between direct Entity destructions and unique_ptr destructions.
This question already has answers here:
Closed 11 years ago.
Possible Duplicate:
Learning C++: polymorphism and slicing
This is building off a question I asked before.
The classes look like this:
class Enemy
{
public:
void sayHere()
{
cout<<"Here"<<endl;
}
virtual void attack()
{
}
};
class Monster: public Enemy
{
public:
void attack()
{
cout<<"RAWR"<<endl;
}
};
class Ninja: public Enemy
{
public:
void attack()
{
cout<<"Hiya!"<<endl;
}
};
I am new to C++ and I'm confused as to why this will only work with pointers (both Ninja and monster are derived from Enemy):
int main()
{
Ninja ninja;
Monster monster;
Enemy *enemies[2];
enemies[0] = &monster;
enemies[1] = &ninja;
for (int i = 0; i < 2; i++)
{
enemies[i]->attack();
}
return 0;
}
Why can't I instead do this?:
int main()
{
Ninja ninja;
Monster monster;
Enemy enemies[2];
enemies[0] = monster;
enemies[1] = ninja;
for (int i = 0; i < 2; i++)
{
enemies[i].attack();
}
return 0;
}
This is a great question that hits at the heart of some of the trickier points of C++ inheritance. The confusion arises because of the difference between static types and dynamic types, as well as the way that C++ allocates storage for objects.
To begin, let's discuss the difference between static and dynamic types. Every object in C++ has a static type, which is the type of the object that is described in the source code. For example, if you try writing
Base* b = new Derived;
Then the static type of b is Base*, since in the source code that's the type you declared for it. Similarly, if you write
Base myBases[5];
the static type of myBases is Base[5], an array of five Bases.
The dynamic type of an object is the type that the object actually has at runtime. For example, if you write something like
Base* b = new Derived;
Then the dynamic type of b is Derived*, since it's actually pointing at a Derived object.
The distinction between static and dynamic types is important in C++ for two reasons:
Assignments to objects are always based on the static type of the object, never the dynamic type.
Invocations of virtual functions only dispatch to the dynamic type if the static type is a pointer or reference.
Let's address each of these in turn.
First, one of the problems with the second version of the code is that you do the following:
Ninja ninja;
Monster monster;
Enemy enemies[2];
enemies[0] = monster;
enemies[1] = ninja;
Let's trace through what happens here. This first creates a new Ninja and Monster object, then creates an array of Enemy objects, and finally assigns the enemies array the values of ninja and monster.
The problem with this code is that when you write
enemies[0] = monster;
The static type of the lhs is Enemy and the static type of the rhs is Monster. When determining how to do an assignment, C++ only looks at the static types of the objects, never the dynamic types. This means that because enemies[0] is statically typed as an Enemy, it has to hold something precisely of type Enemy, never any derived type. This means that when you do the above assignment, C++ interprets this to mean "take the monster object, identify just the part of it that's an Enemy, then copy that part over into enemies[0]." In other words, although a Monster is an Enemy with some extra additions, only the Enemy part of Monster will be copied over into enemies[0] with this line of code. This is called slicing, since you're slicing off part of the object and leaving behind just the Enemy base portion.
In the first piece of code that you posted, you have this:
Ninja ninja;
Monster monster;
Enemy *enemies[2];
enemies[0] = &monster;
enemies[1] = &ninja;
This is perfectly safe, because in this line of code:
enemies[0] = &monster;
The lhs has static type Enemy* and the rhs has type Monster*. C++ legally allows you to convert a pointer to a derived type into a pointer to a base type without any problems. As a result, the rhs monster pointer can be converted losslessly into the lhs type Enemy*, and so the top of the object isn't sliced off.
More generally, when assigning derived objects to base objects, you risk slicing the object. It is always safer and more preferable to store a pointer to the derived object in a pointer to a base object type, because no slicing will be performed.
There's a second point here as well. In C++, whenever you invoke a virtual function, the function is only called on the dynamic type of the object (the type of the object that the object really is at runtime) if the receiver is a pointer or reference type. That is, if you have the original code:
Ninja ninja;
Monster monster;
Enemy enemies[2];
enemies[0] = monster;
enemies[1] = ninja;
And write
enemies[0].attack();
then because enemies[0] has static type Enemy, the compiler won't use dynamic dispatch to determine which version of the attack function to call. The reason for this is that if the static type of the object is Enemy, it always refers to an Enemy at runtime and nothing else. However, in the second version of the code:
Ninja ninja;
Monster monster;
Enemy *enemies[2];
enemies[0] = &monster;
enemies[1] = &ninja;
When you write
enemies[0]->attack();
Then because enemies[0] has static type Enemy*, it can point at either an Enemy or a subtype of Enemy. Consequently, C++ dispatches the function to the dynamic type of the object.
Hope this helps!
Without pointers, your enemies[] array represents a space on the stack sufficient to store two "Enemy" objects-- which means storing all their fields (plus perhaps overhead for a vtable pointer and alignment). Derived classes of Enemy could have additional fields and therefore be larger, so it doesn't let you store a derived object of Enemy in the space reserved for an actual Enemy object. When you do an assignment as in the example, it uses the assignment operator (in this case, defined implicitly)-- which sets the values in the left hand side object's fields to the values of the corresponding fields in the right hand side object, leaving the left-hand-side object's type (and so vtable pointer) unchanged. This is called "object slicing" and is generally to be avoided.
Pointers are all the same size, so you can put a pointer to a derived object of Enemy in the space for a pointer to Enemy and use it just as if it were a pointer to a plain enemy object. Since the pointer to a derived object points to an actual instance of the derived object, calls to virtual functions on the pointer will use the derived object's vtable and give you the desired behavior.
In c++, this is called slicing.
Enemy() creates a Enemy object. If you were to call Enemy().attack(), it would not print anything, because that method is empty.
The only way you can get polymorphic behavior in C++ is using pointers or references.
Using pointers is how polymorphism is implemented in c++ (see here). You'll get a type mismatch error if you try to put a monster or a ninja object into an array of enemies. But "a pointer to a derived class is type-compatible with a pointer to its base class."
That will give you an entirely different result.
In the first scenario with pointers, you'll have Enemy pointers that will point at your Ninja and Monster objects. The objects would be intact, and at runtime the attack() call would call the object's attack() method.
In the other scenario you have actual Enemy objects. When you'll assign the Ninja and Monster objects only the common members will be copied (the rest of the members that don't belong to Enemy will be lost).
Then when you'll call attack() it will be an Enemy attack() (Because they are Enemy objects)
Enemy enemies[2]; creates an array of objects of a concrete type (Enemy). That means, among other things, that all elements of that array have a known size.
How does that work with derived classes which might include other data? It doesn't.
On the other hand, given pointers, it doesn't matter at all. The pointer will point to "something" (the vtable plus data) and the virtual inheritance mechanism somehow figures out what's what and where's what. There may be the same functions, overloaded ones, additional data fields, it will still work.
Assigning monster and ninja to your Enemy array will work, however, when you call the function attack on each one, it will call the base class's attack function. Why? First, when you assign the objects into the Enemy array, you're essentially typecasting those classes so when you interact with its objects, they act like Enemy's as opposed to what they originally were.
If you noticed, you declared your attack function in Enemy as virtual. What this allows is essential in polymorphism. By declaring that function as virtual, you allow subclassed objects (Monster and Ninja, for example) of your Enemy to determine, at run-time, which version of the function attack to use if an Enemy pointer is used. This allows you to use a generic Enemy pointer to access different subclassed objects and still correctly use the right function:
Enemy * ptr;
Enemy copy;
Monster m;
copy = (Enemy)m;
ptr = &m;
copy.attack(); // Calls Enemy's definition of attack, which is undefined.
ptr->attack(); // Even though this is an Enemy pointer, the Monster's definition of attack is used.
By writing
enemies[0] = monster;
you are converting your Monster object to an Enemy object. Every derived class object can be converted automatically to a base class object. This is called object slicing. Once that conversion has happened the Enemy object no longer has any way of remembering that it once used to be a Monster object, it's just a plain Enemy object like any other. So when you call attack, you call Enemy::attack.
This issue doesn't arise in Java because in Java everything is a pointer automatically.
It isn't supported because when you assign a superclass instance the value of a subclass instance, the subclass information not in the superclass is culled. Ergo, some methods - even polymorphic ones - which are subclass-dependent wouldn't work in all situations. The only general-purpose way to guarantee type-safety at compile time is to use the parent class's implementation.
Short version: instances of the parent class may have less state than child class instances, so operations on instances of the parent class have to assume they are those defined for the parent class. Pointers obviate this since child class instances with full state do exist.
Because it is impossible (maybe very difficult and maybe can be done using pointers) to implement such functionality. The main reason is that base and derived objects can have different sizes (sizeof(Enemy) != sizeof(Monster)), and storing monsters in enemies you will just loose some data.