java - resueltos - para que sirve una clase abstracta
C++: cree una clase abstracta con un método abstracto y anule el método en una subclase (3)
¿Cómo crear en C ++ una clase abstracta con algunos métodos abstractos que deseo anular en una subclase? ¿Cómo debería ser el archivo .h
? ¿Hay un .cpp
, si es así, cómo debería verse?
En Java se vería así:
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);
}
Traducir este código a C ++ es suficiente para mí.
Editar:
Creé el código pero cuando trato de iterar sobre los objetos obtengo el siguiente error:
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
Con este código:
vector<GameObject> gameObjects;
for (int i = 0; i < gameObjects.size(); i++) {
GameObject go = (GameObject) gameObjects.at(i);
go.Update();
}
En C ++ usa la palabra clave virtual en sus rutinas, y asigna =0;
en ellos. Al igual que:
class GameObject {
public:
virtual void update()=0;
virtual void paint(Graphics g)=0;
}
Tener un método virtual con un 0
asignado automáticamente hace que su clase sea abstracta.
En Java, todos los métodos son virtual
de forma predeterminada, a menos que los declare final
. En C ++ es al revés: necesita declarar explícitamente sus métodos virtual
. Y para hacer que sean puramente virtuales, debe "inicializarlos" a 0 :-) Si tiene un método virtual puro en su clase, se convierte automáticamente en abstracto, no hay una palabra clave explícita para ello.
En C ++ debe (casi) siempre definir el destructor para sus clases base virtual
, para evitar fugas de recursos complicadas. Así que agregué eso al siguiente ejemplo:
// 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)
{
// ...
}
Las funciones miembro deben declararse virtual
en la clase base. En Java, las funciones de los miembros son virtuales por defecto; no están en C ++.
class GameObject
{
public:
virtual void update() = 0;
virtual void paint(Graphics g) = 0;
}
Lo virtual
hace que una función miembro sea virtual; the = 0
hace que una función miembro sea puramente virtual. Esta clase también es abstracta porque tiene al menos una función miembro virtual que no tiene un anulador final concreto.
Luego en su (s) clase (s) derivada (s):
class Player : public GameObject
{
public:
void update() { } // overrides void GameObject::update()
void paint(Graphics g) { } // overrides void GameObject::paint(Graphics)
}
Si una función miembro se declara virtual en una clase base, automáticamente es virtual en cualquier clase derivada (puede colocar virtual
en la declaración en la clase derivada si lo desea, pero es opcional).