2017-04-09 117 views
0

我试图做一个小的无序映射,我可以用它来永久存储键和值,作为一种字典。类型TengwarChar只是一个具有两个值的对象,一个字符串和一个枚举,稍后我也会添加方法。我使用的标题如下:C++多个定义,即使只有一个定义

#ifndef TENGWARLIBRARY_H 
#define TENGWARLIBRARY_H 

#include "tengwarchar.h" 
#include <unordered_map> 
#include <algorithm> 
#include <string> 

typedef std::unordered_map<std::string, TengwarChar> CharMap; 

extern const CharMap numbers = { 
    {"0", TengwarChar("ð", SHORT)}, 
    {"1", TengwarChar("ñ", SHORT)}, 
    {"2", TengwarChar("ò", SHORT)}, 
    {"3", TengwarChar("ó", SHORT)}, 
    {"4", TengwarChar("ô", SHORT)}, 
    {"5", TengwarChar("õ", SHORT)}, 
    {"6", TengwarChar("ö", SHORT)}, 
    {"7", TengwarChar("÷", SHORT)}, 
    {"8", TengwarChar("ø", SHORT)}, 
    {"9", TengwarChar("ù", SHORT)} 
}; 

std::string translateFromEnglishToTengwar(std::string str); 
std::string translateFromTengwarToEnglish(std::string str); 

#endif // TENGWARLIBRARY_H 

然后,我与它一起去一个简单的测试CPP文件:

#include "tengwarlibrary.h" 

std::string translateFromEnglishToTengwar(std::string str) 
{ 
    std::transform(str.begin(), str.end(), str.begin(), (int (*)(int))std::tolower); 
    return str; 
} 

std::string translateFromTengwarToEnglish(std::string str) 
{ 
    return "Hello world."; 
} 

的问题是,我不断收到“号的多重定义[ abi:cxx11]'的错误,在我的主函数中调用translateFromTengwarToEnglish时,即使我非常确定,我只在头文件中使用标头守护进行了一次定义。在情况下,它可能会帮助,这是我卑微的主CPP文件:

#include "mainwindow.h" 
#include <QApplication> 

#include <iostream> 

#include "utils/tengwarlibrary.h" 

int main(int argc, char *argv[]) 
{ 

    std::string s = "BlaH FElfeFEJI, IEORlfj"; 
    std::cout<<translateFromEnglishToTengwar(s)<<std::endl; 

    QApplication a(argc, argv); 
    MainWindow w; 
    w.show(); 

    return a.exec(); 
} 
+0

您只能在头文件中声明带外部链接的符号。他们的定义需要在翻译单位使用它们。 –

+0

@HenriMenke当我删除'extern const'位并假设它是一个全局变量时,我得到了同样的错误。当我可以在标题中使用初始值设定项时,我并不想将定义放入源文件中。 –

+0

@AndrewLalis你不能。您编写它的方式,每个源文件隐式获取numbers数组的* definition *。你应该在头文件中声明数组,并且在一个源文件中定义它(没有extern关键字)。 –

回答

2

根据C++ standard§3.1.2

的声明是一个定义,除非它宣称的功能,而无需指定函数体,它包含的extern声明符或一个键的说明书和既不是 初始化,也不是一个功能体...

在头文件宣言是带初始值设定项的外部声明。所以这也是一个定义。

正如你已经包括两个tengwarlibrary.h源文件(即一个translateFromTengwarToEnglish()定义何main()定义)两者有numbers定义。因此,错误。

要解决此问题,请在头文件中声明numberextern,并将其初始化为单个源文件。