c ++ LogFile对象编译错误

时间:2013-11-28 08:27:00

标签: c++ string

我在底部创建一个日志文件对象是.h和.cc

贝娄是我得到的错误,请帮忙

  

架构x86_64的未定义符号:
  “LogFile :: log(std :: __ 1 :: basic_string,std :: __ 1 :: allocator>)”,引用   从:         textdisplay中的TextDisplay :: notify(int,int,Cell :: CellType)         Floor :: loadFloor(std :: __ 1 :: basic_string,std :: __ 1 :: allocator>,Player *)in   floor.o         Floor :: isStairwaySet()在floor.o中         floor :: getCellAtCoord(int,int)在floor.o中         floor :: getPossibleSpots(Occupant *,int,int)在floor.o中         floor.o中的Floor :: getNearbyPlayer(int,int)         character.o中的Character :: dealDamage(int)         ...“LogFile :: log(char const *)”,引自:         cc3k.o中的CC3K :: cleanUp()         CC3K :: startGame(Occupant :: SpecificType,std :: __ 1 :: basic_string,   cc3k.o中的std :: __ 1 :: allocator>)         cc3k.o中的CC3K :: step()         cc3k.o中的CC3K :: playerMove(CC3K :: Command,CC3K :: Direction)         Floor :: loadFloor(std :: __ 1 :: basic_string,std :: __ 1 :: allocator>,Player *)in   floor.o         floor :: notify中的floor :: notifyStairwayBeingSet(int,int)         cell.o中的Cell :: removeDeadOccupant()         ...“LogFile :: dlog(std :: __ 1 :: basic_string,std :: __ 1 :: allocator>)”,引用   从:         Merchant.o中的Merchant :: attackStep()“LogFile :: dlog(char const *)”,引自:         Character ::o中的Character :: attack(Character&)         Merchant.o中的Merchant :: attackStep()“LogFile :: getI()”,引自:         cc3k.o中的CC3K :: cleanUp()         CC3K :: startGame(Occupant :: SpecificType,std :: __ 1 :: basic_string,   cc3k.o中的std :: __ 1 :: allocator>)         cc3k.o中的CC3K :: step()         cc3k.o中的CC3K :: playerMove(CC3K :: Command,CC3K :: Direction)         textdisplay中的TextDisplay :: notify(int,int,Cell :: CellType)         Floor :: loadFloor(std :: __ 1 :: basic_string,std :: __ 1 :: allocator>,Player *)in   floor.o         floor :: notify中的floor :: notifyStairwayBeingSet(int,int)         ... ld:找不到架构x86_64的符号

bellow是错误所讨论的一些代码行

LogFile::getI()->log("Error textdisplay.cc 77: Weird cellType given: " + to_string(cellType));
LogFile::getI()->log("Error floor.cc isStairwaySet() 141: Weird values for stairwayRow: " + to_string(stairwayRow) + " stairwayCol: " + to_string(stairwayCol)); 

.h

#ifndef __LOGFILE_H__
#define __LOGFILE_H__

#include <string>

class LogFile
{
    static LogFile *singleton;

    LogFile(std::string fileName);
    ~LogFile();

    int logNum;
    std::string fileName;

    static void cleanUp();

    public:

        enum Error {};
        //must be called before use, fileName to log too
        static LogFile *initInstance(std::string fileName);
        static LogFile *getI();

        void log(std::string error);
        void log(const char *error);
        void dlog(std::string error);
        void dlog(const char *error);
        bool hasLoged();
        int getNumLogs();
};

#include "logfile.h"

.CC

#include "logfile.h"
#include <ofstream>
#include <cstdlib>

using namespace std;

static LogFile *LogFile::singleton = NULL;

void LogFile::cleanUp()
{
    delete singleton;
}

LogFile::LogFile(std::string fileName): logNum(0), fileName(fileName){}

LogFile::~LogFile(){}

//must be called before use, fileName to log too
LogFile *LogFile::initInstance(std::string fileName)  //static
{
    if(singleton)
    {
        singleton->log("Error: logfile.cc initInstance() 19: Calling this function more than once is wrong implementation");
        return singleton;
    }else
    {
        singleton = new LogFile(fileName);      
#ifdef REPRAND
singleton->log("#define REPRAND");
#endif
#define DEBUG
singleton->log("#define DEBUG");
#endif  
        atexit(cleanUp)
        return singleton;
    }
}

LogFile *LogFile::getI() //static
{
    if(!singleton)
    {
        LogFile::getI()->log("Error: logfile.cc getInstance() 32: Calling getInstance() without having first called initInstance()");
    }else
    {
        return singleton;
    }
}

void LogFile::log(std::string error)
{
    ofstream ofs;
    ofs.open(fileName.c_str(), ofstream::out | ofstream::app);

    ofs << error << endl;

    if(!ofs.good)
        LogFile::getI()->log("Error writeToFile() 47: output file stream is not good");

    logNum ++;
}

void LogFile::log(char *error)
{
    log(string(error));
}

void LogFile::dlog(std::string error)
{
#ifdef DEBUG
log(error);
#endif
}

void LogFile::dlog(char *error)
{
    dlog(string(error));
}

bool LogFile::hasLoged()
{
    return (logNum > 0);
}

int LogFile::getNumLogs()
{
    return logNum;
}

4 个答案:

答案 0 :(得分:2)

void log(std::string error)

没有定义您想要的成员函数。你必须说:

void LogFile::log(std::string error)

您的定义刚刚定义了一个名为log的裸函数,该函数有效,因此编译器在链接之前不会抱怨。

答案 1 :(得分:0)

您在方法体声明中缺少类名。

例如在.cc中而不是:

static LogFile *getI()

写:

static LogFile* LogFile::getI()

您的日志方法正文应如下所示:

void LogFile::Log(std::string error)
{
    ...
}

您必须为LogFile类中的每个方法执行此操作。

接下来你有一些ifdef宏并在它下面:

#define DEBUG
singleton->log("#define DEBUG");
#endif

这看起来像是复制粘贴错误,应该有#ifdef而不是#define

答案 2 :(得分:0)

我不确定它是否是拼写错误,但在您的“日志”方法中,您有以下内容:

ofs << error); // Where does the ending paranthesis come from?

无需进一步查看,看看是否能解决您的错误。 :)

答案 3 :(得分:0)

你越来越近了。希望你没有得到确切的错误,只是一个子集。

这个定义:

void LogFile::log(std::string error)

现在匹配声明,但

void LogFile::log(char *error)

与声明的稍有不同:

void log(const char *error);

参数类型和返回值必须完全匹配。