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