编译为可执行文件时的未定义引用

时间:2016-03-15 18:29:50

标签: c++

当我尝试将所有目标文件编译成可执行文件时,我收到错误

lab5.o:lab5.cpp: undefined reference to 'Card::suitMap'

我认为正确链接依赖关系是一个问题,但我真的不知道如何验证我是否在正确的轨道上。

这是包含main功能的源文件:

#include "Card.h"
#include "Deck.h"
#include <iostream>

using namespace std;

int main()
{
    Deck* deck1 = new Deck();
    Deck* deck2 = new Deck();

    for(int i = 0; i < deck1->deck.size(); i++)
    {
        Card card = deck1->draw();
        cout << card.getSuit() << " " << card.getValue() << endl;
    }

    deck2->shuffle();
    for(int i = 0; i < deck2->deck.size(); i++)
    {
        Card card = deck2->draw();
        cout << card.getSuit() << " " << card.getValue() << endl;
    }
}

这是我的Card.h,其中包含suitMap

#ifndef CARD_H
#define CARD_H
#include <string>
#include <map>

class Card {
private:
    int value;
    int suit;
public:
    std::map <int, std::string> suitMap;
    Card(int value, int suit);
    int getValue() { return this->value; }
    std::string getSuit() { return this->suitMap.find(this->suit)->second; }
};

#endif

我不确定我的makefile是否包含问题,但这里也是如此

CC=g++
CFLAGS=-c -Wall -g -std=c++11
LDFLAGS=
SOURCES=lab5.cpp Card.cpp Deck.cpp
OBJECTS=$(SOURCES:.cpp=.o)
EXECUTABLE=lab5

all: $(SOURCES) $(EXECUTABLE)

$(EXECUTABLE): $(OBJECTS)
    $(CC) $(LDFLAGS) $(OBJECTS) -o $@

.cpp.o:
    $(CC) $(CFLAGS) $< -o $@

clean:
    rm -f *.o $(EXECUTABLE)

2 个答案:

答案 0 :(得分:4)

您之前必须已经suitMap表示static,并且在更改之后不知何时没有获得干净的构建。确保在修改标题后执行完全干净的构建。

答案 1 :(得分:1)

您的问题是由于makefile中的缺陷造成的。正确设计的makefile会自动管理所有依赖项,从而无需运行make clean修复构建。

下面是一个可以防止出现问题的makefile示例。它不是进行增量构建,而是始终重新编译每个源文件。当您创建更大的项目时,这种方法最终可能会变得太慢,在这种情况下,您将需要投资更复杂的构建管理解决方案。对于现有项目,使用此makefile,在现代PC上构建可能需要大约一秒钟。

EXECUTABLE = lab5
SOURCES += lab5.cpp Card.cpp Deck.cpp

CXXFLAGS += -Wall -Werror
CXXFLAGS += -std=c++11
CXXFLAGS += -g

.PHONY: build
build:
    $(CXX) $(CXXFLAGS) $(LDFLAGS) $(SOURCES) $(LDLIBS) -o $(EXECUTABLE)

.PHONY: clean
clean:
    rm -f $(EXECUTABLE)