0
\$\begingroup\$

So I am creating a game with C++ and SDL. I have a "gameobject" header file and no cpp (I do not need it) the game object has 2 functions void render() & tick().

The player class inherits from the gameobject. the problem is I don't know how to inherit functions. I tried virtual but I still can't figure it out. I am used to Java so C++ is quite complicated.

My code:

gameobject.h :

#include <SDL2/SDL.h>
#include <SDL2/SDL_image.h>
#include "game.h"

class gameobject
{
    public:
        virtual ~gameobject();

        void virtual tick() = 0;
        void render();

    protected:

        int width = pos.w;
        int height = pos.h;
        int posx = pos.x;
        int posy = pos.y;

        float velox;
        float veloy;

        SDL_Rect crop;
        SDL_Rect pos;
};

#endif // GAMEOBJECT_H

player.h:

#ifndef PLAYER_H
#define PLAYER_H

#include "gameobject.h"

class gameobject;

class player : public gameobject
{
    public:

    private:

        player(SDL_Renderer* renderer,int pwidth,int pheight);
        ~player();
};
#endif // PLAYER_H

player.cpp :

#include "player.h"

player::player(SDL_Renderer* renderer,int pwidth, int pheight)
{
    this->pos.w = pwidth;
    this->pos.h = pheight;
};

void player::tick(){} /// the problem here
\$\endgroup\$
1
\$\begingroup\$

In the future, make sure to write the error the compiler gives.

In c++, for a function to work, you need (generally) two things: a declaration, and a definition. (In some situations, both can be combined.)

However, here,

void virtual tick() = 0;

will only declare the function. You basically tell the world "I, the mighty gameobject, hereby declare this function, now you, subclasses, define one." (This is because you use = 0.)

You need to declare and define such a function in your player class so you can use it there. Here you define a function that you did not declare, so you need to declare it.

Declare (in the header file):

class player : public gameobject
{
    public:
        void tick() override;
    ...
\$\endgroup\$
  • \$\begingroup\$ but why i use inheritance if will declare it in all derived classes @Vaillancourt \$\endgroup\$ – younlok Nov 8 at 15:43
  • \$\begingroup\$ The one you declare in gameobject represents a "contract", every gameobject is guaranteed to have that service/feature. You don't have to declare it in every derived classes, only those that will define it (e.g. gameobject -> player -> player_blue | player_red: player does not have to have it if you don't intended to instantiate it, but player_blue and player_red will. It's otherwise the way the language is built. \$\endgroup\$ – Vaillancourt Nov 8 at 16:06
1
\$\begingroup\$

Java is object oriented, that is, it makes heavy use of inheritance, but the syntax is a little different.

In C++ we declare a base class, which can be viewed as an interface, thusly:

class Base
{
public:
    Base(){} //simple constructor
    virtual void foo() = 0; //this is known as a pure virtual function
    virtual ~Base(){} //virtual destructor
};

Now we can derive a child class:

class A:
    public Base
{
public:
    A(){}
    virtual void foo() override { //do something }
    virtual ~A(){}
};

Ok, now that we have defined our base and child class, we can explain how this works.

When we instantiate, that is, create an instance of the class A, we can do so thusly:

Base* b = new A();

Then we can call foo:

b->foo();

What happens, is that when your program runs, for the class family, a virtual function table, or vtable, is created for virtual functions.

Think of it like this, in simplistic terms:

b: ctor : 0001 //address of Base constructor
        : 0002 //address of A constructor
 : foo  : 0000 //address of Base::foo(): null, as it is declared as pure virtual (0)
        : 0003 //address of A::foo() 
 : dtor : 0004 //address of Base::~Base()
        : 0005 //address of A:~Base()

This is a table of pointers to functions. When a function is called, the table is referenced, and the pointer to the appropriate function retrieved, and then executed.

Every child class declaration must provide a definition for any virtual functions declared in a parent class, and if using a *.cpp (definition file), the header must also have a declaration of the function.

The virtual keyword tells the compiler to create a vtable entry for the class, and the override keyword tells the compiler that for that class you are overriding any previous implementations of the foo() function

So, armed with that information, we can see that in your child class, you have not provided a declaration, nor implementation, of the tick() pure virtual function declared in your base class.

Thus, when you try to compile your code, you will be given an error telling you that you have created a child class (Player), which does not implement the interface specified in GameObject.

Long story short: The compiler will not allow instantiation of a class which does not implement it's parent class's interface.

See Here for more information.

\$\endgroup\$

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.