C ++: хранение потомков класса в переменных с его типом - PullRequest
1 голос
/ 30 октября 2010

В настоящее время я работаю над проектом 2D-игры и хочу переключиться с Delphi на C ++.

В Delphi я мог бы объявить массив, который имел тип класса Entity, и я мог быположить Entity s, а также объекты классов, которые являются производными от Entity.

Это было бы очень важно для меня, так как кажется логичным, что все объекты должны храниться и управлятьсяв одном месте.

  • Возможно ли это в C ++?
  • (почему бы и нет, если оно есть в Delphi?)

  • Какие еще варианты для достижения чего-то подобного у меня есть?

Мне нужно сделать что-то вроде ниже:

#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?
}

Я надеюсь, что сделал самдостаточно ясно, и я очень признателен за вашу помощь

Ответы [ 4 ]

5 голосов
/ 30 октября 2010

... Потому что (без дополнительных модификаторов) все типы C ++ являются типами значений, говоря в терминах Delphi или C #. Вы в основном делаете это:

 point = camera;

Этот оператор вызывает сгенерированный компилятором оператор присваивания:

Entity& Entity::operator(const Entity& pOther) ...

Это работает, поскольку const Camera& конвертируется в const Entity&. Но внутри присваивания нет информации о части объекта Camera, pOther разделен на Entity объект. Вы получаете требуемое поведение, сообщая компилятору C ++, что вы хотите обрабатывать объекты как ссылочные типы (указатели):

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) );
}
5 голосов
/ 30 октября 2010

Используйте boost :: ptr_vector для хранения полиморфных объектов или контейнера интеллектуальных указателей, например, vector >, если вам нужно поделиться / переместить их в другое место.

1 голос
/ 31 октября 2010

Ваша проблема в том, что вы смешиваете способ работы Delphi и C ++ с объектами.

В случае C ++ экземпляр класса можно использовать тремя способами:

  • в качестве значения
  • как ссылка
  • как указатель

Только два последних способа выражают то же поведение, которое вы ожидаете от кода Delphi.

В вашем примере вы создаете объекты-значения, это означает, что когда вы пытаетесь назначить камеру на объект, копируется часть объекта, принадлежащая камере, но ничего больше.

Вы должны изменить свойкод для использования указателей вместо

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

Чтобы не связываться с указателями напрямую, более современная идиома C ++ заключается в использовании интеллектуальных указателей.Как показывает ответ paul_71.

0 голосов
/ 30 октября 2010

Полагаю, вы ищете шаблоны C ++.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...