0

I'm working on a basic game loop with a GameObject/Entity system, but I'm really new to C/C++ (but I have used the bindings for Raylib, which is the library I am using, in C# before, so I understand how it works).

I've been having some struggles mainly getting my grips around how C/++ handles pointers and also virtual functions. I have no errors and I have found my problem after inserting a few debug calls, which show that my background isn't actually having any operations performed on it, despite them being called, which leads be to believe that my dodgy virtual functions are to blame inside the class Background.

Honestly, I'd love any help I can get (please roast my code, I need to learn a LOT, I have also removed superficial code):

//main.cpp
int main(void)
{   
    // Init
    std::vector<GameObject*> gameObjects;

    Background bg;
    gameObjects.push_back(&bg);

    // Main game loop
    while (!WindowShouldClose())
    {
        // Update
        for (GameObject* gameObject : gameObjects)
        {
            gameObject->Update();
        }
        // Draw
        for (GameObject *gameObject : gameObjects)
        {
            gameObject->Render();
        }
    }
    //End
    return 0;
}

//gameobject.h
class GameObject
{
    public:
        GameObject(void) {};
        virtual void Update() = 0;
        virtual void Render() = 0;
        ~GameObject(void) {};
};

//background.h
#include "gameobject.h"

class Background : public GameObject
{
    public:
        Background(void){};
        virtual void Update(){};
        virtual void Render(){};
        ~Background(void){};
    private:
        Texture texture;
};

//background.cpp
#include "background.h"
#include "gameobject.h"
#include <iostream>

//Constructor
Background::Background()
{
    ...
}
//Methods
void Background::Update()
{
    ...
}
void Background::Render()
{
    ...
}
//Deconstructor
Background::~Background()
{
    ...
}

The problem comes however, that none of my functions inside of the Background class are called. I don't think that could be a result of any of my header locks, but I could add them in if anyone wants to look at them.

Edit: Solved! (I need to remember to mark this solved soon)

class GameObject
{
    public:
        GameObject(void) = default;
        virtual void Update() =0;
        virtual void Render() =0;
        ~GameObject(void) = default;
};
class Background : public GameObject
{
    public:
        Background(void);
        virtual void Update();
        virtual void Render();
        ~Background(void);
    private:
        Texture texture;
};
Chadderbox
  • 55
  • 1
  • 5
  • You've removed superficial code, and you've also removed non-superficial code. As presented, there's no way to distinguish between the virtual functions being called and the virtual functions not being called because none of them do anything. This is why it's important to make a minimal _reproducible_ example. – Nathan Pierson Jul 21 '21 at 18:16
  • 5
    `virtual void Update(){};` Dare I ask what those `{}` are doing there? Same with Render. This project shouldn't even link, much less run, since you're providing duplicate implementations. That is, unless... you're not actually linking your background.cpp object code in the first place (which I highly suspect, since it shouldn't even *compile*; the compiler will bark about how those member functions are already implemented whence it encounters them in the .cpp file). – WhozCraig Jul 21 '21 at 18:16
  • Show how you build your project. – n. 1.8e9-where's-my-share m. Jul 21 '21 at 18:19
  • @WhozCraig I'm not sure, I was told to put them there, but if I remove them then I get an error saying that there is an undefined reference. – Chadderbox Jul 21 '21 at 18:23
  • @n.1.8e9-where's-my-sharem. I build with mingw32, using a makefile: g++ ../main.cpp -o game.exe -O2 -Wall -Wno-missing-braces -I ../include/ -L ../lib/ -lraylib -lopengl32 -lgdi32 -lwinmm – Chadderbox Jul 21 '21 at 18:24
  • 2
    "I was told to put them there" by *who* ?? That means you're not compiling+linking your Background.cpp file into your final executable. – WhozCraig Jul 21 '21 at 18:24
  • 3
    Well, there's your problem. You need to compile `background.cpp` as well. – Nathan Pierson Jul 21 '21 at 18:24
  • Functions in your `background.cpp` are not called because you never show them to the compiler. – n. 1.8e9-where's-my-share m. Jul 21 '21 at 18:26
  • I #include the background.h into my main – Chadderbox Jul 21 '21 at 18:26
  • Okay? That has nothing to do with whether you compile `background.cpp` and make the resulting object file visible to the linker. – Nathan Pierson Jul 21 '21 at 18:27
  • `background.h` is not `background.cpp`. – n. 1.8e9-where's-my-share m. Jul 21 '21 at 18:29
  • So if I add ../background.cpp to my Makefile, what would I change about the code to make it work after that? – Chadderbox Jul 21 '21 at 18:31
  • Drop the `{}` member function definitions in your header files and leave just the declarations. – Nathan Pierson Jul 21 '21 at 18:32
  • @NathanPierson That gives me an error saying that the constructor and destructor are undefined references. – Chadderbox Jul 21 '21 at 18:34
  • 1
    *Which* constructor and destructor? `Background` or `GameObject`? If it's `GameObject`, then you still need to have definitions for them _somewhere_, whether that's `gameobject.cpp` or inline in `gameobject.h`. (As written, they could also just both be `GameObject() = default; virtual ~GameObject() = default;` because they don't do anything.) – Nathan Pierson Jul 21 '21 at 18:37
  • @NathanPierson Sorry, Background's constructor and destructor – Chadderbox Jul 21 '21 at 18:38
  • Thanks a lot @NathanPierson – Chadderbox Jul 21 '21 at 18:44

0 Answers0