Drin kadriu Drin kadriu - 3 months ago 24
C++ Question

C++ getting LNK2019 error, even though no circular dependency, and nothing included twice

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

Answer

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