【问题标题】:Can't compile the project after splitting the source files to cpp and h, getting "undefined refernce to..."将源文件拆分为 cpp 和 h 后无法编译项目,得到“未定义的引用...”
【发布时间】:2013-06-09 12:39:58
【问题描述】:

我有一个项目,其中只有 .cpp 文件。它运行良好,但后来我意识到这不是一个好习惯,所以我决定将它拆分为 .cpp.h 文件。尽管如此,现在我无法编译该项目。有人可以看看源代码并告诉我问题出在哪里吗?

Bot.h

#ifndef BOT_H
#define BOT_H

#include <vector>
#include <string>
#include <cstdlib>

using namespace std;
/**
 * Class that represents casual Bot - the parent of other bots
 */
class Bot {
public:
    Bot();
    virtual ~Bot();
    bool initialized;
    string getRandomMessage();
    string getName();
protected:
    vector<string> messages;
    string name;
};

#endif  /* BOT_H */

Bot.cpp

#include <vector>
#include <string>
#include <cstdlib>
#include "Bot.h"

using namespace std;
string Bot::getRandomMessage() {
    int r = static_cast<double> (std::rand()) / RAND_MAX * this->messages.size();
    return messages[r];
}
Bot::Bot(){    
}
Bot::~Bot(){    
}
string Bot::getName() {
    return this->name;
}

继承自Bot类的类示例:

GrumpyBot.h

#ifndef GRUMPYBOT_H
#define GRUMPYBOT_H
#include "Bot.h"

class GrumpyBot : public Bot{
public:
    GrumpyBot();
    GrumpyBot(const GrumpyBot& orig);
    virtual ~GrumpyBot();
};

#endif  /* GRUMPYBOT_H */

GrumpyBot.cpp

#include "GrumpyBot.h"
GrumpyBot::GrumpyBot() {

    initialized = true;
    this->name = "GrumpyBot";
    messages.push_back("I hate dogs.");
    messages.push_back("I hate cats.");
    messages.push_back("I hate goats.");
    messages.push_back("I hate humans.");
    messages.push_back("I hate you.");
    messages.push_back("I hate school.");
    messages.push_back("I hate love.");
}

到目前为止还可以,但是Server.cpp 类中出现了问题,我尝试在其中创建这些类的新实例并调用它们的函数。 我将#include "Bot.h"#include "GrumpyBot.h" 都包含在其中,编译器不断向我发送/home/ubuntu/NetBeansProjects/SemestralniPraceChat/./Server.cpp:335: undefined reference to 'GrumpyBot::GrumpyBot()' 之类的消息

我的 makefile 如下所示:

#macros
Remove=rm -rf
Doxygen=Doxyfile
RUN=./dvoram64
FLAGS=-Wall -pedantic -Wno-long-long -O0 -ggdb -lncurses -pthread -g
OBJECTS=main.o Bot.o Server.o Client.o

#generates final binary and documentation
all:    $(Doxygen)
    make compile

#build into final binary
compile: $(RUN)

#run program
run: $(RUN)
    $(RUN)


clean:
    $(Remove) dvoram64
    $(Remove) $(OBJECTS)

#generate documentation in '<login>/doc' folder
doc: $(Doxygen) /*
    ( cd ./ | doxygen $(Doxygen))

#rules how to compile into the executalble file
$(RUN): $(OBJECTS)

Bot.o: ./Bot.cpp ./Bot.h
    g++ $(FLAGS) -c ./Bot.cpp

DummyBot.o: ./DummyBot.cpp ./DummyBot.h ./Bot.h
    g++ $(FLAGS) -c ./DummyBot.cpp

GrumpyBot.o: ./GrumpyBot.cpp ./GrumpyBot.h ./Bot.h
    g++ $(FLAGS) -c ./GrumpyBot.cpp

JokerBot.o: ./JokerBot.cpp ./JokerBot.h ./Bot.h
    g++ $(FLAGS) -c ./JokerBot.cpp

WeatherBot.o: ./WeatherBot.cpp ./WeatherBot.h ./Bot.h
    g++ $(FLAGS) -c ./WeatherBot.cpp

Client.o: ./Client.cpp
    g++ $(FLAGS) -c ./Client.cpp

main.o: ./main.cpp ./Server.cpp ./Bot.h ./JokerBot.h ./WeatherBot.h ./GrumpyBot.h ./DummyBot.h ./Client.cpp
    g++ ./main.cpp $(FLAGS) -o ./dvoram64

Server.o: ./Server.cpp ./Bot.h ./JokerBot.h ./WeatherBot.h ./GrumpyBot.h ./DummyBot.h
    g++ $(FLAGS) -c ./Server.cpp

【问题讨论】:

    标签: c++ inheritance compilation header


    【解决方案1】:

    未定义的引用是链接器错误,您没有为链接过程传递对象。

    在 makefile 中,将 main.o: 行替换为

    main.o: main.cpp 
         g++ $(FLAGS) -c main.cpp 
    

    $(FLAGS) 中删除-lncurses 并添加:

    link: <all the o files>
       g++ <all the o files> -lncurses -pthread -o dvoram64 
    

    然后调用:

    make link
    

    将创建正确链接的可执行文件。

    编辑:

    如果你定义了 $(OBJECTS) 变量,链接应该是:

    link: $(OBJECTS)
         g++ $(OBJECTS) -lncurses -pthread -o dvoram64
    

    【讨论】:

    • 我尝试根据您的建议编辑我的Makefile,但它根本没有帮助...我当前的Makefile 在这里pastebin.com/LMv0tu0v 这就是我得到的我正在尝试编译 pastebin.com/AG9kieyW 。任何想法,我做错了什么? :-/
    • 根据您当前的 Makefile 添加到答案
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2011-03-13
    相关资源
    最近更新 更多