Singleton code linker errors in vc 9.0. Runs fine in linux compiled with gcc
        Posted  
        
            by user306560
        on Stack Overflow
        
        See other posts from Stack Overflow
        
            or by user306560
        
        
        
        Published on 2010-04-01T04:36:49Z
        Indexed on 
            2010/04/01
            4:43 UTC
        
        
        Read the original article
        Hit count: 415
        
I have a simple logger that is implemented as a singleton. It works like i want when I compile and run it with g++ in linux but when I compile in Visual Studio 9.0 with vc++ I get the following errors. Is there a way to fix this? I don't mind changing the logger class around, but I would like to avoid changing how it is called.
1>Linking...
1>loggerTest.obj : error LNK2005: "public: static class Logger * __cdecl Logger::getInstance(void)" (?getInstance@Logger@@SAPAV1@XZ) already defined in Logger.obj
1>loggerTest.obj : error LNK2005: "public: void __thiscall Logger::log(class std::basic_string<char,struct std::char_traits<char>,class std::allocator<char> > const &)" (?log@Logger@@QAEXABV?$basic_string@DU?$char_traits@D@std@@V?$allocator@D@2@@std@@@Z) already defined in Logger.obj
1>loggerTest.obj : error LNK2005: "public: void __thiscall Logger::closeLog(void)" (?closeLog@Logger@@QAEXXZ) already defined in Logger.obj
1>loggerTest.obj : error LNK2005: "private: static class Logger * Logger::_instance" (?_instance@Logger@@0PAV1@A) already defined in Logger.obj
1>Logger.obj : error LNK2001: unresolved external symbol "private: static class std::basic_string<char,struct std::char_traits<char>,class std::allocator<char> > Logger::_path" (?_path@Logger@@0V?$basic_string@DU?$char_traits@D@std@@V?$allocator@D@2@@std@@A)
1>loggerTest.obj : error LNK2001: unresolved external symbol "private: static class std::basic_string<char,struct std::char_traits<char>,class std::allocator<char> > Logger::_path" (?_path@Logger@@0V?$basic_string@DU?$char_traits@D@std@@V?$allocator@D@2@@std@@A)
1>Logger.obj : error LNK2001: unresolved external symbol "private: static class boost::mutex Logger::_mutex" (?_mutex@Logger@@0Vmutex@boost@@A)
1>loggerTest.obj : error LNK2001: unresolved external symbol "private: static class boost::mutex Logger::_mutex" (?_mutex@Logger@@0Vmutex@boost@@A)
1>Logger.obj : error LNK2001: unresolved external symbol "private: static class std::basic_ofstream<char,struct std::char_traits<char> > Logger::_log" (?_log@Logger@@0V?$basic_ofstream@DU?$char_traits@D@std@@@std@@A)
1>loggerTest.obj : error LNK2001: unresolved external symbol "private: static class std::basic_ofstream<char,struct std::char_traits<char> > Logger::_log" (?_log@Logger@@0V?$basic_ofstream@DU?$char_traits@D@std@@@std@@A)
The code, three files Logger.h Logger.cpp test.cpp
#ifndef __LOGGER_CPP__
#define __LOGGER_CPP__
#include "Logger.h"
Logger* Logger::_instance = 0;
//string Logger::_path = "log";
//ofstream Logger::_log;
//boost::mutex Logger::_mutex;
Logger* Logger::getInstance(){
  { 
    boost::mutex::scoped_lock lock(_mutex);
    if(_instance == 0) {
      _instance = new Logger;
   _path = "log";
    }
  } //mutex
  return _instance;
}
void Logger::log(const std::string& msg){
  {
    boost::mutex::scoped_lock lock(_mutex);
    if(!_log.is_open()){
      _log.open(_path.c_str());
    }
    if(_log.is_open()){
    _log << msg.c_str() << std::endl;
    }
  }
}
void Logger::closeLog(){
  Logger::_log.close();
}
#endif
` ...
#ifndef __LOGGER_H__
#define __LOGGER_H__
#include <iostream>
#include <string>
#include <fstream>
#include <boost/thread/mutex.hpp>
#include <boost/thread.hpp>
using namespace std;
class Logger {
  public:
    static Logger* getInstance();
    void log(const std::string& msg);
    void closeLog();
  protected:
    Logger(){}
  private:
    static Logger* _instance;
    static string _path;
    static bool _logOpen;
    static ofstream _log;
    static boost::mutex _mutex; //check mutable
};
#endif
test.cpp `
#include <iostream>
#include "Logger.cpp"
using namespace std;
int main(int argc, char *argv[])
{
  Logger* log = Logger::getInstance();
  log->log("hello world\n");
  return 0;
}
© Stack Overflow or respective owner