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