19

How to create in C++ an abstract class with some abstract methods that I want to override in a subclass? How should the .h file look? Is there a .cpp, if so how should it look?

In Java it would look like this:

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);
}

Translating this code to C++ is enough for me.

Edit:

I created the code but when I try to iterate over the objects I get following 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

With this code:

vector<GameObject> gameObjects;

for (int i = 0; i < gameObjects.size(); i++) {
    GameObject go = (GameObject) gameObjects.at(i);
    go.Update();
}
Martijn Courteaux
  • 67,591
  • 47
  • 198
  • 287
  • Your "in my game loop" code is... incomplete, at best. What is `objects`? If you don't already have one, I strongly recommend getting one of the beginner books from [The Definitive C++ Book Guide and List](http://stackoverflow.com/questions/388242/the-definitive-c-book-guide-and-list). – James McNellis May 29 '10 at 22:54
  • You might also consult Herb Sutter's article, [Virtuality](http://www.gotw.ca/publications/mill18.htm), which discusses many best practices when using virtual functions and inheritance in C++. – James McNellis May 29 '10 at 22:59

3 Answers3

26

In Java, all methods are virtual by default, unless you declare them final. In C++ it's the other way around: you need to explicitly declare your methods virtual. And to make them pure virtual, you need to "initialize" them to 0 :-) If you have a pure virtual method in your class, it automatically becomes abstract - there is no explicit keyword for it.

In C++ you should (almost) always define the destructor for your base classes virtual, to avoid tricky resource leaks. So I added that to the example below:

// 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)
{
     // ...
}
Péter Török
  • 114,404
  • 31
  • 268
  • 329
  • 2
    @Martijn, you can't have a `vector` since that would store its elements by value, but `GameObject`, being abstract, can have no instances. You need a `vector` or preferably a `vector>` to store polymorphic objects. See also the comments for James McNellis' answer. – Péter Török May 30 '10 at 15:31
  • Why you need to declare methods in GameObject.h, if they already declared? – HasaDev Sep 13 '16 at 19:55
  • Since C++11 you should additionally use the `overrride` specifier in order to specify virtual function overrides. See: https://en.cppreference.com/w/cpp/language/override. – damb Aug 09 '21 at 15:05
7

The member functions need to be declared virtual in the base class. In Java, member functions are virtual by default; they are not in C++.

class GameObject
{
public:
    virtual void update() = 0;
    virtual void paint(Graphics g) = 0;
}

The virtual makes a member function virtual; the = 0 makes a member function pure virtual. This class is also abstract because it has at least one virtual member function that has no concrete final overrider.

Then in your derived class(es):

class Player : public GameObject
{
public:
    void update() { }          // overrides void GameObject::update()
    void paint(Graphics g) { } // overrides void GameObject::paint(Graphics)
}

If a member function is declared virtual in a base class, it is automatically virtual in any derived class (you can put virtual in the declaration in the derived class if you'd like, but it's optional).

James McNellis
  • 348,265
  • 75
  • 913
  • 977
4

In C++ you use the keyword virtual on your routines, and assign =0; into them. Like so:

class GameObject {
public:
    virtual void update()=0;
    virtual void paint(Graphics g)=0; 

}

Having a virtual method with a 0 assigned into it automagically makes your class abstract.

T.E.D.
  • 44,016
  • 10
  • 73
  • 134