Singleton causing linker errors: "already defined" - c++

I wrote a simple class which manages the current execution session. Therefore, I decided to use a singleton pattern but the compilation crashes at linked step. This is the error:
error LNK2005: "class Session * session" (?session##3PAVSession##A) already defined in ClientTsFrm.obj
(...)client\FrmSaveChat.obj TeamTranslate
error LNK2005: "class Session * session" (?session##3PAVSession##A) already defined in ClientTsFrm.obj
(...)client\Login.obj TeamTranslate
error LNK2019: unresolved external symbol "protected: __thiscall Session::Session(void)" (??0Session##IAE#XZ)
referenced in function "public: static class Session * __cdecl Session::Instance(void)" (?Instance#Session##SAPAV1#XZ)
(...)client\Session.obj TeamTranslate
error LNK2001: unresolved external symbol "private: static char const * const Session::_nick" (?_nick#Session##0PBDB)
(...)client\Session.obj TeamTranslate
error LNK2001: unresolved external symbol "private: static char const * const Session::_service" (?_service#Session##0PBDB)
(...)client\Session.obj TeamTranslate
error LNK2001: unresolved external symbol "private: static char const * const Session::_serverAddress" (?_serverAddress#Session##0PBDB)
(...)client\Session.obj TeamTranslate
error LNK2001: unresolved external symbol "private: static char const * const Session::_googleAPI" (?_googleAPI#Session##0PBDB)
(...)client\Session.obj TeamTranslate
error LNK2001: unresolved external symbol "private: static char const * const Session::_language" (?_language#Session##0PBDB)
(...)client\Session.obj TeamTranslate
error LNK2001: unresolved external symbol "private: static int Session::_numbLanguageSelected" (?_numbLanguageSelected#Session##0HA)
(...)client\Session.obj TeamTranslate
error LNK2001: unresolved external symbol "private: static char const * const Session::_translationEngine" (?_translationEngine#Session##0PBDB)
(...)client\Session.obj TeamTranslate
error LNK1120: 8 unresolved externals
(...)client\bin\TeamTranslate.exe TeamTranslate
IntelliSense: identifier "wxZipStreamLink" is undefined
(..)\include\wx\zipstrm.h 417 5
session.h (singleton)
#ifndef __SESSION_H__
#define __SESSION_H__
#include <cstring>
#include <stdio.h>
class Session {
public:
static Session* Instance();
void setNick(char* nick);
const char* getNick();
void setService(char* serv);
const char* getService();
void setLanguage(char* lang);
const char* getLanguage();
const char* getServerAddress();
void setServerAddress(char *sv);
void setGoogleAPIKey(char* code);
const char* getGoogleAPIKey();
void setNumbLanguageSelected(int v);
int getNumbLanguageSelected();
const char* Session::getTranslationEngine();
void Session::setTranslationEngine(char *sv);
char* Session::getGoogleURLTranslation();
void update();
bool read();
protected:
Session();
private:
static Session* _instance;
static const char* _nick; // client nickname
static const char* _service; // service used to translation (Google, Bing,....)
static const char* _serverAddress;
static const char* _googleAPI;
static const char* _language;
static int _numbLanguageSelected;
static const char* _translationEngine;
};
#endif
Session.cpp
#include "Session.h"
Session* Session::_instance = 0;
Session* Session::Instance() {
if (_instance == 0) {
_instance = new Session;
_instance->read();
}
return _instance;
}
void Session::setGoogleAPIKey(char* code){
_googleAPI = strdup(code);
}
const char* Session::getGoogleAPIKey(){
return _googleAPI;
}
void Session::setLanguage(char* lang){
_language = strdup(lang);
}
const char* Session::getLanguage(){
return _language;
}
void Session::setNick(char* nick){
_nick = strdup(nick);
}
const char* Session::getNick(){
return _nick;
}
void Session::setService(char* serv){
_service = strdup(serv);
}
const char* Session::getService(){
return _service;
}
const char* Session::getServerAddress(){
return _serverAddress;
}
void Session::setServerAddress(char *sv){
_serverAddress = strdup(sv);
}
void Session::setNumbLanguageSelected(int v){
this->_numbLanguageSelected = v;
}
int Session::getNumbLanguageSelected(){
return _numbLanguageSelected;
}
const char* Session::getTranslationEngine(){
return _translationEngine;
}
void Session::setTranslationEngine(char* sv){
_translationEngine = strdup(sv);
}
void Session::update(){
FILE* config = fopen("conf\\config.txt", "w");
fprintf(config, "%s\n", _serverAddress);
fprintf(config, "%s\n", _nick);
fprintf(config, "%d\n", _numbLanguageSelected);
fprintf(config, "%s\n", _language);
fprintf(config, "%s", _translationEngine);
fflush(config);
fclose(config);
}
bool Session::read(){
FILE * config;
if (config = fopen("conf\\config.txt", "r"))
{
fscanf(config, "%s", _serverAddress);
fscanf(config, "%s", _nick);
fscanf(config, "%d", _numbLanguageSelected);
fscanf(config, "%s", _language);
fscanf(config, "%s", _translationEngine);
fflush(config);
fclose(config);
return true;
} else
return false;
}
char* Session::getGoogleURLTranslation(){
return "https://www.googleapis.com/language/translate/v2?key=";
}
Example about how I call the singleton:
#include "../data/Session.h"
static Session* session = Session::Instance();
Can you help me to fix the errors?
thanks in advance.

One of your headers (which you didn't show, but it is included in both "ClientTsFrm.cpp" and "FrmSaveChat.cpp") defines a variable called "session" of type Session*.
The other errors are caused by your forgetting to define most static members of Session.

Related

Unresolved external symbol for the mentioned code in description

#include <iostream>
class t1
{
public:
~t1();
static t1& fun();
private:
t1()
{
}
};
t1& t1::fun()
{
return t1();
}
int main()
{
t1::fun();
return 0;
}
I am getting unresolved external symbol. please help. the errors are below
Error 2 error LNK2019: unresolved external symbol "public: __thiscall t1::~t1(void)" (??1t1##QAE#XZ) referenced in function "public: static class t1 & __cdecl t1::fun(void)" (?fun#t1##SAAAV1#XZ) D:\LXI\LXIRef\RefDesign_V01.00\Software\Solution\TestWebServer\TestWebServer.obj TestWebServer
Error 3 error LNK1120: 1 unresolved externals D:\LXI\LXIRef\RefDesign_V01.00\Software\Solution\Debug\TestWebServer.exe 1 1 TestWebServer
Give definitions to constructor and destructor.
#include <iostream>
class t1
{
public:
~t1() {} // <<<< defined here
static t1& fun();
private:
t1() {} // << defined here
};
t1& t1::fun()
{
return t1();
}
int main()
{
t1::fun();
return 0;
}

Linker can't find a namespace's functions

See code below. There's something wrong with it, because the linker is complaining it can't find the Memory's functions, but I can't figure out why.
memory.h
#pragma once
#include "includes.h" //it just includes other strandard headers.
class MemoryUnit
{
public:
MemoryUnit() {}
virtual int getValue() = 0;
virtual int getSize() = 0;
virtual void setValue(int) = 0;
virtual ~MemoryUnit() {};
};
class Byte : public MemoryUnit
{
int value;
public:
static int size;
Byte(int byte) :value(byte) {};
int getSize() { return size; }
int getValue() { return value; };
void setValue(int byte) { value = byte; }
~Byte() {};
};
namespace Memory
{
extern int size;
extern MemoryUnit** map;
void checkAddress(int address);
int read(int adress);
MemoryUnit* getOperation(int address);
void write(int adress, MemoryUnit* data);
void writeByte(int adress, int data);
}
memory.cpp
#include "includes.h"
#include "memory.h"
#include "simulator.h" // it contains only externed constants.
namespace Memory
{
int size = 0;
MemoryUnit** map = NULL;
inline MemoryUnit* getOperation(int address)
{
return map[address];
}
inline void checkAddress(int address)
{
if (address < 0 || address >= MAX_MEMORY_SIZE)
throw std::out_of_range("Invalid memory address.");
}
inline int read(int address)
{
checkAddress(address);
return map[address]->getValue();
}
inline void write(int address, MemoryUnit* data)
{
checkAddress(address);
delete map[address];
map[address] = data;
}
inline void writeByte(int address, int data)
{
checkAddress(address);
map[address]->setValue(data);
}
}
Everywhere the class/namespace memory.h declares is includes memory.h. Is here anything wrong in the code below?
Edit:
I'm using Visual Studio 2015.
Errors I got when building the project:
LNK1120 5 unresolved externals simulator.exe
LNK2019 unresolved external symbol "void __cdecl Memory::writeByte(int,int)" referenced in function "void __cdecl ALU::setFlags(int)" alu.obj
LNK2001 unresolved external symbol "void __cdecl Memory::writeByte(int,int)" cu.obj
LNK2019 unresolved external symbol "class MemoryUnit * __cdecl Memory::getOperation(int)" referenced in function "void __cdecl CU::run(void)" cu.obj
LNK2001 unresolved external symbol "void __cdecl Memory::writeByte(int,int)" helpers.obj
LNK2019 unresolved external symbol "void __cdecl Memory::write(int,class MemoryUnit *)" referenced in function "void __cdecl readProgramCommands(void)" helpers.obj
LNK2001 unresolved external symbol "public: virtual int __thiscall MemoryPointer::getValue(void)" helpers.obj
LNK2001 unresolved external symbol "public: virtual int __thiscall IndirectMemoryPointer::getAddress(void)" helpers.obj
LNK2001 unresolved external symbol "void __cdecl Memory::writeByte(int,int)" main.obj
alu.h and alu.cpp for the first error:
//alu.h
#pragma once
#include "includes.h"
#include "operation.h"
namespace ALU
{
int operation(Operation* op);
void setFlags(int result);
}
//alu.cpp
#include "includes.h"
#include "simulator.h"
#include "alu.h"
#include "memory.h"
#include "operation.h"
namespace ALU
{
int operation(Operation* operation)
{
// ...
setFlags(result);
return result;
}
inline void setFlags(int result)
{
Memory::writeByte(FLAG_Z, result == 0);
// ...
}
}
You need to put the inline function definition inside your header file (they both must appear in every translation unit where they are used), you can separate declaration and definition but both must be in the header file. Also they must be declared as inline.
N4140 dcl.fct.spec 7.1.2.4
An inline function shall be defined in every translation unit in which it is odr-used and shall have exactly
the same definition in every case (3.2). [ Note: A call to the inline function may be encountered before its
definition appears in the translation unit. —end note ] If the definition of a function appears in a translation
unit before its first declaration as inline, the program is ill-formed.
When you're using inline functions or methods, their definitions should be visible for every source unit that uses them. You defined your inline functions in Memory.cpp, that's why you get 'unresolved' linker error.
To fix your problem you can:
Remove inline modifier and keep functions definitions in Memory.cpp.
Keep inline modifier but move functions definitions to Memory.h.

Unresolved external symbol (singleton class C++) [duplicate]

This question already has answers here:
What is an undefined reference/unresolved external symbol error and how do I fix it?
(39 answers)
Closed 7 years ago.
I already looked up some answers in Stackoverflow for this type of problem, none of which are helping me out. This question describes how to resolve this error, and that I should provide a definition and not just a declaration. I've done that, but I'm still getting the following error:
Error 13 error LNK2019: unresolved external symbol "private: __thiscall NetworkManager::NetworkManager(void)" (??0NetworkManager##AAE#XZ) referenced in function "public: static class NetworkManager * __cdecl NetworkManager::Instance(void)" (?Instance#NetworkManager##SAPAV1#XZ) C:\Users\HIDDEN\Documents\AGK Projects\C++ Libraries\apps\template_windows_vs2013\NetworkManager.obj Template
Here's the code:
NetworkManager.h
#ifndef _H_NETWORKMANAGER_
#define _H_NETWORKMANAGER_
#include<iostream>
#include<vector>
class NetworkManager
{
private:
NetworkManager();
static NetworkManager * netManager;
public:
int networkID;
static NetworkManager * Instance();
int HostNetwork(std::string netName, std::string hostName, int port);
int JoinNetwork(std::string netName, std::string clientName);
bool IsNetworkActive(int netID);
};
#endif
NetworkManager.cpp
#include<iostream>
#include "NetworkManager.h"
#include "template.h"
NetworkManager * NetworkManager::netManager = NULL;
NetworkManager * NetworkManager::Instance()
{
if (!netManager)
netManager = new NetworkManager;
return netManager;
}
int NetworkManager::HostNetwork(std::string netName, std::string hostName, int port)
{
int networdID__;
const char * netName__ = netName.c_str();
const char * hostName__ = hostName.c_str();
networdID__ = agk::HostNetwork(netName__, hostName__, port);
return networdID__;
}
int NetworkManager::JoinNetwork(std::string netName, std::string clientName)
{
int networdID__;
const char * netName__ = netName.c_str();
const char * clientName__ = clientName.c_str();
networdID__ = agk::JoinNetwork(netName__, clientName__);
return networdID__;
}
bool NetworkManager::IsNetworkActive(int netID)
{
switch (agk::IsNetworkActive(netID))
{
case 0: return false; break;
case 1: return true; break;
}
}
You declared NetworkManager::NetworkManager() in the header file but there is no implementation of it in the source file.

Linker Error with std::multiset insert operation

I have copied header file and cpp file from one of my old project( build in VS-2010) into new project( developing it in QT5.1) and have encounter this weird error
1>Message_list.obj : error LNK2019: unresolved external symbol "public: bool __thiscall Message_list::NoMessageTime::operator()(struct Message const &,struct Message const &)const " (??RNoMessageTime#Message_list##QBE_NABUMessage##0#Z) referenced in function "bool __cdecl std::_Debug_lt_pred<class Message_list::NoMessageTime,struct Message,struct Message>(class Message_list::NoMessageTime,struct Message &,struct Message const &,wchar_t const *,unsigned int)" (??$_Debug_lt_pred#VNoMessageTime#Message_list##UMessage##U3##std##YA_NVNoMessageTime#Message_list##AAUMessage##ABU3#PB_WI#Z)
I have no idea how to solve it.
In my header file
Message_list.h
#include <set>
#include <QSTRING>
#include "Message.h"
class Message_list
{
class NoMessageTime
{
public:
bool operator ()( const Message& left, const Message& right ) const;
};
typedef std::multiset<Message, NoMessageTime> MessageSet;
public:
void add( const Message& message );
private:
/** Inserts an item into the correct place in the list
*/
void Message_list::insert_item( const Message& message );
MainWindow* dialog_;
MessageSet messages_;
};
Message_list.cpp
void Message_list::addd( const Message& message )
{
QMutex mutex;
mutex.lock();
// Do something here
messages_.insert( message ); // error comes here
mutex.unlock();
}
Same files compiled successfully in vs-2010..

C++ LNK2019 ( between project classes )

I have an very strange error: when I want to use the SocialServer::Client class from my SocialServer::Server class, the linker threw me two LNK2019 errors :
Error 1 error LNK2019: unresolved external symbol "public: void __thiscall SocialServer::Client::Handle(void)" (?Handle#Client#SocialServer##QAEXXZ) referenced in function "private: static unsigned int __stdcall SocialServer::Server::listenThread(void *)" (?listenThread#Server#SocialServer##CGIPAX#Z) C:\Users\benjamin\Documents\Visual Studio 2010\Projects\FCX Social Server\SocialServer Core\Server.obj SocialServer Core
Error 2 error LNK2019: unresolved external symbol "public: __thiscall SocialServer::Client::Client(unsigned int)" (??0Client#SocialServer##QAE#I#Z) referenced in function "private: static unsigned int __stdcall SocialServer::Server::listenThread(void *)" (?listenThread#Server#SocialServer##CGIPAX#Z) C:\Users\benjamin\Documents\Visual Studio 2010\Projects\FCX Social Server\SocialServer Core\Server.obj SocialServer Core
However , these 2 missing function are correctly implemented :
Client.h
#pragma once
#include "dll.h"
namespace SocialServer
{
class __social_class Client
{
public:
Client(SOCKET sock);
~Client();
void Handle();
private:
static unsigned __stdcall clientThread(void* value);
SOCKET _socket;
uintptr_t _thread;
unsigned int _thread_id;
};
}
Client.cpp
#pragma once
#include "Client.h"
namespace SocialServer
{
Client::Client(SOCKET socket)
{
this->_socket = socket;
}
Client::~Client()
{
}
void Client::Handle()
{
std::cout << " New client " << std::endl;
this->_thread = _beginthreadex(NULL, 0, Client::clientThread, &this->_socket, CREATE_SUSPENDED, &this->_thread_id);
ResumeThread((HANDLE)this->_thread);
}
unsigned __stdcall Client::clientThread(void* value)
{
// Some code to execute here ...
}
}
Where does the problem comes from ?
i've found the solution.
In a function that's used by _beginthreadex() (with unsigned __stdcall) , always add a return at the end.