Как создать в C++ абстрактный класс с некоторыми абстрактными методами, которые я хочу переопределить в подклассе? Как должен .h
взгляд файла? Есть ли a .cpp
, раз так, как это должно посмотреть?
В Java это было бы похоже на это:
abstract class GameObject
{
public abstract void update();
public abstract void paint(Graphics g);
}
class Player extends GameObject
{
@Override
public void update()
{
// ...
}
@Override
public void paint(Graphics g)
{
// ...
}
}
// In my game loop:
List<GameObject> objects = new ArrayList<GameObject>();
for (int i = 0; i < objects.size(); i++)
{
objects.get(i).update();
}
for (int i = 0; i < objects.size(); i++)
{
objects.get(i).paint(g);
}
Перевод этого кода к C++ достаточно для меня.
Править:
Я создал код, но когда я пытаюсь выполнить итерации по объектам, я получаю следующую ошибку:
Game.cpp:17: error: cannot allocate an object of abstract type ‘GameObject’
GameObject.h:13: note: because the following virtual functions are pure within ‘GameObject’:
GameObject.h:18: note: virtual void GameObject::Update()
GameObject.h:19: note: virtual void GameObject::Render(SDL_Surface*)
Game.cpp:17: error: cannot allocate an object of abstract type ‘GameObject’
GameObject.h:13: note: since type ‘GameObject’ has pure virtual functions
Game.cpp:17: error: cannot declare variable ‘go’ to be of abstract type ‘GameObject’
GameObject.h:13: note: since type ‘GameObject’ has pure virtual functions
С этим кодом:
vector<GameObject> gameObjects;
for (int i = 0; i < gameObjects.size(); i++) {
GameObject go = (GameObject) gameObjects.at(i);
go.Update();
}
В Java все методы по умолчанию virtual
, если только вы не объявите их final
. В C++ все наоборот: вы должны явно объявить свои методы виртуальными
. А чтобы сделать их чисто виртуальными, нужно "инициализировать" их в 0 :-) Если в вашем классе есть чисто виртуальный метод, он автоматически становится абстрактным - для этого нет явного ключевого слова.
В C++ вы должны (почти) всегда определять деструктор для ваших базовых классов virtual
, чтобы избежать хитрых утечек ресурсов. Поэтому я добавил это в пример ниже:
// GameObject.h
class GameObject
{
public:
virtual void update() = 0;
virtual void paint(Graphics g) = 0;
virtual ~GameObject() {}
}
// Player.h
#include "GameObject.h"
class Player: public GameObject
{
public:
void update();
void paint(Graphics g);
}
// Player.cpp
#include "Player.h"
void Player::update()
{
// ...
}
void Player::paint(Graphics g)
{
// ...
}
Функции-члены должны быть объявлены виртуальными
в базовом классе. В Java функции-члены являются виртуальными по умолчанию; в C++ это не так.
class GameObject
{
public:
virtual void update() = 0;
virtual void paint(Graphics g) = 0;
}
Символ virtual
делает функцию-член виртуальной; символ = 0
делает функцию-член чисто виртуальной. Этот класс также является абстрактным, потому что у него есть по крайней мере одна виртуальная функция-член, у которой нет конкретного конечного переопределителя.
Затем в вашем производном классе (классах):
class Player : public GameObject
{
public:
void update() { } // overrides void GameObject::update()
void paint(Graphics g) { } // overrides void GameObject::paint(Graphics)
}
Если функция-член объявлена виртуальной в базовом классе, она автоматически становится виртуальной в любом производном классе (вы можете поместить virtual
в объявление в производном классе, если хотите, но это необязательно).
В C ++ вы используете ключевое слово virtual в своих подпрограммах и присваиваете им = 0;
. Примерно так:
class GameObject {
public:
virtual void update()=0;
virtual void paint(Graphics g)=0;
}
Наличие виртуального метода с назначенным ему 0
автоматически делает ваш класс абстрактным.