C++: Storing childs of a class in variables with it's type
I am currently working on a 2D game project and I want to switch from Delphi to C++.
In Delphi, I could declare an array which had the type of a class Entity
, and I could put Entity
s as well as objects of classes which are derived from Entity
into it.
This would be very important for me, as it seems logical that all entities should be stored and managed in one place.
- Is this possible in C++?
(Why not if it is in Delphi?)
What other choices to achieve something similar do I have?
I would need to do something like below:
#include <vector>
using namespace std;
class Entity
{
public:
int id;
};
class Camera : Entity
{
public:
int speed;
};
int main()
{
Entity point;
Camera camera;
vector<Entity> vec开发者_如何学运维;
vec.push_back( point );
vec.push_back( camera ); //Why can't I do that?
}
I hope I have made myself clear enough and I'd really appreciate your help
Use a boost::ptr_vector<Entity> to store polymorphic objects, or a container of smart pointers, e.g. vector<boost::shared_ptr<Entity> >, if you need to share/move them elsewhere.
...Because (without further modifiers) all C++ types are value types, speaking in terms of Delphi or C#. You are basically doing this:
point = camera;
This statement invokes the compiler generated assignment operator:
Entity& Entity::operator(const Entity& pOther) ...
This works, since const Camera&
is convertible to const Entity&
. But inside the assignment there is no information about the 'Camera
' part of the object, the pOther
gets 'sliced' into Entity
object. You get the required behaviour by telling the C++ compliler that you want to treat the objects as reference types (pointers):
int main()
{
vector<std::shared_ptr<Entity> > vec;
vec.push_back( std::shared_ptr<Entity>(new Point) );
vec.push_back( std::shared_ptr<Entity>(new Camera) );
}
Your problem is that you are mixing the way Delphi and C++ deal with objects.
In C++ case a class instance can be used in three ways:
- as a value
- as a reference
- as a pointer
Only the two last ways express the same behaviour as you would expect from Delphi code.
In your example, you are creating value objects, this means that when you try to assign a Camera to an Entity, the sub part of Entity that belongs to Camera gets copied, but nothing else.
You should change your code to use pointers instead,
int main()
{
Entity* point = new Entity;
Camera* camera = new Camera;
vector<Entity*> vec;
vec.push_back( point );
vec.push_back( camera );
// don't forget to delete them, when you're done with the list
for (vector<Entity*>::iterator iter = vec.begin(); iter != vec.end(); ++iter)
delete (*iter);
}
enter code here
To avoid messing with pointers directly, a more modern C++ idiom is to make use of smart pointers. As shown by paul_71's answer.
I guess you are looking for C++ templates.
精彩评论