0

Okay so i'm trying to create an Entity Component System, and until now its been working pretty decent, but now i've encountered some linker errors that i'm not sure why, i've tried different variations for hours but i can't get this to work, i know i have made a very silly mistake but i can't find it, So here are all my files:(general does nothing!, and i haven't touched main, i suppose the linker errors are caused from the Entity and Public files)

and basically i have a giant wrapper thats 'Public.h' that includes necessary headers, and has some reusable methods, here is Public.h:

#pragma once
#include <iostream>
#include <vector>
#include <string>

using namespace std;
static int counter = 0;
static int NamCounter = 0;
static int TagCounter = 0;
static vector <string> AllNames;
static vector <string> AllTags;
//static vector <Entity> AllEntities;

//static void AddToAllENT(Entity* newE){
//}

int GetCounter();
int GetNamCounter();
int GetTagCounter();
string UniqueName(string uN = "lol");
string UniqueTag(string uT = "lol");

All fine, and here is 'Public.cpp':

#include "Public.h"

//static void AddToAllENT(Entity* newE){
//}

static int GetCounter(){
    return counter++;
}
static int GetNamCounter(){
    return TagCounter++;
}
static int GetTagCounter(){
    return NamCounter++;
}
static string UniqueName(string uN){
    if (uN == "lol")
        return "_Entity" + to_string(GetNamCounter());
    for (int i = 0; i < AllTags.size(); i++){
        if (AllTags.at(i) == uN)
            return "_Entity" + to_string(GetNamCounter());
    }
    AllTags.push_back(uN);
    return uN;
}
static string UniqueTag(string uT){
    if (uT == "lol")
        return "_EntityTag" + to_string(GetTagCounter());
    for (int i = 0; i < AllTags.size(); i++){
        if (AllTags.at(i) == uT)
            return "_EntityTag" + to_string(GetTagCounter());
    }
    AllTags.push_back(uT);
    return uT;
}

Then my problem lies in the Entity files, here is my Entity.h:

#pragma once

class Entity
{
private:
    int ID;
    string Name;
    string Tag;
    //vector <Component> AllComps;
public:
    friend bool operator==(const Entity& left, const Entity& right){
        return ((left.Name == right.Name) && (left.Tag == right.Tag));
    }
    friend bool operator!=(const Entity& left, const Entity& right){
        return !(left == right);
    }
    Entity();
    Entity(const Entity&);
    Entity(string);
    Entity(string, string);
    ~Entity();
    int GetID();
    string GetName();
    string GetTag();
    void Start();
    void Update();
    void SetAll(string, string);
    void PrintAll();
};

And here is my Entity.cpp:

#include "Public.h"
#include "Entity.h"

Entity::Entity()
{
    ID = GetCounter();
    this->Name = UniqueName();
    this->Tag = UniqueTag();
}
Entity::Entity(string name){
    ID = GetCounter();
    this->Name = UniqueName(name);
    this->Tag = UniqueTag();
}
Entity::Entity(string name, string tag){
    ID = GetCounter();
    this->Name = UniqueName(name);
    this->Tag = UniqueTag(tag);
}

int Entity::GetID(){ return this->ID; }
string Entity::GetName(){ return this->Name; }
string Entity::GetTag(){ return this->Tag; }
void Entity::PrintAll(){
    cout << "NAME: \"" << this->Name << "\" TAG: \"" << this->Tag << "\" ID: \"" << this->ID << "\"" << endl;
}
void Entity::SetAll(string newn, string newt){
    this->Tag = newt;
    this->Name = newn;
}

void Entity::Start(){

}
void Entity::Update(){

}

Entity::~Entity()
{
}

And All this i causing me a lot of linker errors, which i'm not sure why, i'm pretty sure everything is linked correctly, and nothing is included twice etc, but i still get theese errors:

Error   1   error LNK2019: unresolved external symbol "int __cdecl GetCounter(void)" (?GetCounter@@YAHXZ) referenced in function "public: __thiscall Entity::Entity(class std::basic_string<char,struct std::char_traits<char>,class std::allocator<char> >,class std::basic_string<char,struct std::char_traits<char>,class std::allocator<char> >)" (??0Entity@@QAE@V?$basic_string@DU?$char_traits@D@std@@V?$allocator@D@2@@std@@0@Z)    C:\Users\drin-_000\Documents\Visual Studio 2013\Projects\ECSystem\ECSystem\Entity.obj   ECSystem
Error   2   error LNK2019: unresolved external symbol "class std::basic_string<char,struct std::char_traits<char>,class std::allocator<char> > __cdecl UniqueName(class std::basic_string<char,struct std::char_traits<char>,class std::allocator<char> >)" (?UniqueName@@YA?AV?$basic_string@DU?$char_traits@D@std@@V?$allocator@D@2@@std@@V12@@Z) referenced in function "public: __thiscall Entity::Entity(class std::basic_string<char,struct std::char_traits<char>,class std::allocator<char> >,class std::basic_string<char,struct std::char_traits<char>,class std::allocator<char> >)" (??0Entity@@QAE@V?$basic_string@DU?$char_traits@D@std@@V?$allocator@D@2@@std@@0@Z)  C:\Users\drin-_000\Documents\Visual Studio 2013\Projects\ECSystem\ECSystem\Entity.obj   ECSystem
Error   3   error LNK2019: unresolved external symbol "class std::basic_string<char,struct std::char_traits<char>,class std::allocator<char> > __cdecl UniqueTag(class std::basic_string<char,struct std::char_traits<char>,class std::allocator<char> >)" (?UniqueTag@@YA?AV?$basic_string@DU?$char_traits@D@std@@V?$allocator@D@2@@std@@V12@@Z) referenced in function "public: __thiscall Entity::Entity(class std::basic_string<char,struct std::char_traits<char>,class std::allocator<char> >,class std::basic_string<char,struct std::char_traits<char>,class std::allocator<char> >)" (??0Entity@@QAE@V?$basic_string@DU?$char_traits@D@std@@V?$allocator@D@2@@std@@0@Z)    C:\Users\drin-_000\Documents\Visual Studio 2013\Projects\ECSystem\ECSystem\Entity.obj   ECSystem
Error   4   error LNK1120: 3 unresolved externals   C:\Users\drin-_000\Documents\Visual Studio 2013\Projects\ECSystem\Debug\ECSystem.exe    ECSystem
kooldart
  • 61
  • 11
  • Why are you declaring the functions as `static` in `Public.cpp`? – NathanOliver Aug 29 '16 at 11:40
  • Do you know what `static` does with function definitions? – rustyx Aug 29 '16 at 11:40
  • i've used static because i thought its the better way to share a function(EDIT: i meant variable not function), and the only way to get/set a static variable is by a static method(thats what i thought before). – kooldart Aug 29 '16 at 11:57

1 Answers1

3

Remove static from the implementation of those GetCounter, GetNamCounter, GetTagCounter, UniqueName,UniqueTag( functions in public.cpp - they are not meant to be static

[EDIT] other linkage errors.

Also, in public.h, replace static by extern in the declaration of

extern int counter = 0;
extern int NamCounter = 0;
extern int TagCounter = 0;
extern vector <string> AllNames;
extern vector <string> AllTags;

and implement them in public.cpp

int counter = 0;
int NamCounter = 0;
int TagCounter = 0;
vector <string> AllNames;
vector <string> AllTags;

See extern here

Community
  • 1
  • 1
Adrian Colomitchi
  • 3,974
  • 1
  • 14
  • 23
  • That: 1. it does not find a non-static GetCounter() function that is why you get the linker error and also static-functions may don't do what you think it will. – Hayt Aug 29 '16 at 11:48
  • i did that and now i got different errors for all of them, one of them is: -Error 3 error LNK2005: "int counter" (?counter@@3HA) already defined in Entity.obj C:\Users\drin-_000\Documents\Visual Studio 2013\Projects\ECSystem\ECSystem\Public.obj ECSystem EDIT: nevermind, i added back static to the variables – kooldart Aug 29 '16 at 11:55
  • @Drinkadriu "EDIT: nevermind, i added back static to the variables" - **don't**. Every .obj file will have their own copies of those variables, which will mean they won't be global. (to your merit, you have the courage to make new mistakes instead of just repeating the old ones. Now, you only need to convince yourself that reading the manual and understanding it saves time on the long run :) ) – Adrian Colomitchi Aug 29 '16 at 12:10