0

I discovered a G++ compiler linking problem. Let`s say I have a main file and two pairs of "library files" (.h + .cc./.cpp):

  • foundations.h - foundations.cc
  • scenes.h - scenes.cc
  • worldsystemdemo.cc (main file)
  • [config.h] <-- insignifant, just there to store some "define"´s

So, here´s a kind of structure of my "include tree" and the commands I used in order to link my finished executable: Include Tree / Building Process Edit: Of course I mean g++ -c %blabla%.cc

So, when I run the final linking command, I get these errors: G++ Error Message

It says that it can´t find some certain constructors in my Vector2-Class (declared in foundations.h & defined in foundations.cc).

So why does the linker not find these?

Thank you for your time!
Best regards

At the end I put in the file contents:

config.h

#pragma once

#define MATRIX_WIDTH 64
#define MATRIX_HEIGHT 32
#define SLOWDOWN_GPIO 4

#define MATRIX_HEADER "../../rpi-rgb-led-matrix/include/led-matrix.h"

foundations.h

#pragma once

#include <stdint.h>

#define tmpl template<typename T>

tmpl struct Vector2;
struct Bitmap;
struct Camera;

tmpl
struct Vector2
{
    T x, y;
    Vector2(); 
    Vector2(const T& q);
    Vector2(const T& x, const T& y);
    T getArea() const;
    Vector2<T> operator +(const Vector2<T>& other);
    void operator +=(const Vector2<T>& other);
};


struct Bitmap
{
    Vector2<unsigned> size;
    Bitmap(const Vector2<unsigned>& size, const uint16_t* const colors);
    Bitmap(const Vector2<unsigned>& size, uint16_t* const colors);
    Bitmap(const Bitmap& other);
    ~Bitmap();
    void operator =(const Bitmap& other);
    uint16_t* operator[](const unsigned& x) const;
private:
    uint16_t *colors;
    bool requireColorsDelete;
    void cpyColors(const uint16_t* colors, const unsigned& size);
    void checkDelColors();
};

struct Camera
{
    Vector2<int> capturingPosition;
    Vector2<int> capturingSize;
    Vector2<int> projectionSize;
};

foundations.cc

#include "../gameinclude/foundations.h"
#include "../gameinclude/config.h"

#include <cstring>

tmpl Vector2<T>::Vector2() : x(0), y(0) {}
tmpl Vector2<T>::Vector2(const T& q) : x(q), y(q) {};
tmpl Vector2<T>::Vector2(const T& x, const T& y) : x(x), y(y) {}
tmpl T Vector2<T>::getArea() const { return x * y; }
tmpl Vector2<T> Vector2<T>::operator +(const Vector2<T>& other)
{
    return Vector2<T>(x + other.x, y + other.y);
}
tmpl void Vector2<T>::operator +=(const Vector2<T>& other)
{
    *this = *this + other;
}

Bitmap::Bitmap(const Vector2<unsigned>& size, const uint16_t* const colors) :
    size(size),
    colors(new uint16_t[size.getArea()]),
    requireColorsDelete(true)
{
    cpyColors(colors, size.getArea());
}

Bitmap::Bitmap(const Vector2<unsigned>& size, uint16_t* const colors) :
    size(size),
    colors(colors),
    requireColorsDelete(false) {}

Bitmap::Bitmap(const Bitmap& other) : 
    size(other.size),
    colors(other.requireColorsDelete ? new uint16_t[other.size.getArea()] : other.colors),
    requireColorsDelete(other.requireColorsDelete)
{
    if (other.requireColorsDelete)
    {
        cpyColors(other.colors, other.size.getArea());
    }
}

Bitmap::~Bitmap()
{
    checkDelColors();
}

void Bitmap::operator =(const Bitmap& other)
{
    if (this != &other)
    {
        checkDelColors();
        size = other.size;
        if (other.requireColorsDelete)
        {
            unsigned area = other.size.getArea();
            colors = new uint16_t[area];
            cpyColors(other.colors, area);
        }
        else
        {
            colors = other.colors;
        }
        requireColorsDelete = other.requireColorsDelete;
    }
}

uint16_t* Bitmap::operator[](const unsigned& x) const { return &colors[x * size.y]; }
void Bitmap::cpyColors(const uint16_t* colors, const unsigned& size) { std::memcpy(this->colors, colors, size * sizeof(uint16_t)); }
void Bitmap::checkDelColors() { if (requireColorsDelete) { delete[] colors; } }

scenes.h

#pragma once

#include "foundations.h"

#include <vector>

struct GameObject;
class Scene;

struct GameObject
{
    Vector2<float> position;
    Vector2<unsigned> size;
    Vector2<float> speed;
    GameObject(const Vector2<float>& position, const Vector2<unsigned>& size, const uint16_t& color);
    GameObject(const Vector2<float>& position, const Vector2<unsigned>& size, const Bitmap& image);
    GameObject(const Vector2<float>& position, const Vector2<unsigned>& size, Bitmap* const image);
    GameObject(const GameObject& other);
    ~GameObject();
    void operator=(const GameObject& other);
private:
    bool requireImageDelete;
    Bitmap *image;
    void checkDelImage();
};

class Scene
{
    unsigned _frameCount = 0;
    std::vector<GameObject*> _gameObjects;
    Scene* const parentScene;
    Scene* activeScene = this;
    Camera camera;
public:
    const unsigned& frameCount = _frameCount;
    const std::vector<GameObject*>& gameObjects = _gameObjects;
    Scene(Scene* const parentScene);
    ~Scene();
    bool inside(const GameObject* go) const;
    GameObject* instantiate(const GameObject& goSrc);
    bool destroy(const GameObject* go);
    virtual void frame();
    virtual void gameObjectFrame(GameObject* const go);
    void loadSubScene(Scene* scene);
    void unloadSubScene();
    void finishSubScene();
};

scenes.cc

#include "../gameinclude/scenes.h"

#include <algorithm>

GameObject::GameObject(const Vector2<float>& position, const Vector2<unsigned>& size, const uint16_t& color) : 
    GameObject(position, size, Bitmap(Vector2<unsigned>(1), &color)) {}
GameObject::GameObject(const Vector2<float>& position, const Vector2<unsigned>& size, const Bitmap& image) :
    position(position),
    size(size),
    image(new Bitmap(image)),
    requireImageDelete(true) {}
GameObject::GameObject(const Vector2<float>& position, const Vector2<unsigned>& size, Bitmap* const image) : 
    position(position),
    size(size),
    image(image),
    requireImageDelete(false) {}
GameObject::GameObject(const GameObject& other) : 
    position(other.position),
    size(other.size),
    speed(other.speed),
    image(other.requireImageDelete ? new Bitmap(*other.image) : other.image),
    requireImageDelete(other.requireImageDelete) {}
GameObject::~GameObject() { checkDelImage(); }

void GameObject::operator=(const GameObject& other)
{
    if (this != &other)
    {
        checkDelImage();
        position = other.position;
        size = other.size;
        speed = other.speed;
        if (other.requireImageDelete)
        {
            image = new Bitmap(*other.image);
        }
        else
        {
            image = other.image;
        }
        requireImageDelete = other.requireImageDelete;
    }
}

void GameObject::checkDelImage() { if (requireImageDelete) { delete image; } };


Scene::Scene(Scene* const parentScene) : parentScene(parentScene) {}
Scene::~Scene() { std::for_each(_gameObjects.begin(), _gameObjects.end(), [] (GameObject* go) { delete go; } ); }
bool Scene::inside(const GameObject* go) const
{
    return std::find(_gameObjects.begin(), _gameObjects.end(), go) != _gameObjects.end();
}
GameObject* Scene::instantiate(const GameObject& goSrc)
{
    _gameObjects.push_back(new GameObject(goSrc));
    return _gameObjects.back();
}
bool Scene::destroy(const GameObject* go)
{
    auto it = std::remove(_gameObjects.begin(), _gameObjects.end(), go);
    bool successful = it != _gameObjects.end();
    if (successful) { delete go; }
    _gameObjects.erase(it, _gameObjects.end());
    return successful;
}
void Scene::frame()
{
    if (activeScene == this)
    {
        std::for_each(_gameObjects.begin(), _gameObjects.end(), [=] (GameObject* const go) { this->gameObjectFrame(go); });
        ++_frameCount;
    }
    else
    {
        activeScene->frame();
    }
}
void Scene::gameObjectFrame(GameObject* const go) { go->position += go->speed; }
void Scene::loadSubScene(Scene* scene) { activeScene = scene; }
void Scene::unloadSubScene() { activeScene = this; }
void Scene::finishSubScene() { if (parentScene != nullptr) { parentScene->unloadSubScene(); } }

worldsystemdemo.cc

#include "../gameinclude/scenes.h"

#include <iostream>

int main()
{
    Scene scene(nullptr);
    GameObject goSrc = GameObject(Vector2<float>(), Vector2<unsigned>(1), 6000);
    GameObject *go = scene.instantiate(goSrc);
    GameObject *go2 = scene.instantiate(goSrc);
    std::cout << scene.inside(go) << std::endl;
    std::cout << scene.inside(go2) << std::endl;
}
DesktopDev
  • 21
  • 3
  • Without code you've written for Vector2 it may be hard to help you. – Karol T. Nov 22 '21 at 12:52
  • unrelated to your issue but please don't get into habits like `#define tmpl template` especially in header files, you'll eventually break something and it makes your code much harder to read for other people – Alan Birtles Nov 22 '21 at 13:05
  • Nevermind, this fixed my problem: In foundations.cc I put in these lines of code: template class Vector2; template class Vector2; template class Vector2; So I have to say to the compiler, for what kind of classes I use my class template. – DesktopDev Nov 23 '21 at 14:29

0 Answers0