C++ 多个定义,即使只给出一个定义
Posted
技术标签:
【中文标题】C++ 多个定义,即使只给出一个定义【英文标题】:C++ Multiple definitions even though only one definition is given 【发布时间】:2017-04-09 07:50:36 【问题描述】:我正在尝试制作一个小的无序映射,我可以用它来永久存储键和值,作为一种字典。 TengwarChar
类型只是一个有两个值的对象,一个字符串和一个枚举,稍后我也会添加方法。我使用的标头如下:
#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.";
问题是,在我的主函数中调用translateFromTengwarToEnglish
时,我不断收到“数字的多重定义[abi:cxx11]”错误,尽管我相当确定我只在标题中定义了一次文件,也使用标题保护。如果它可能有帮助,这是我不起眼的主要 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();
【问题讨论】:
您只能在头文件中声明带有外部链接的符号。它们的定义需要在使用它们的翻译单元中。 @HenriMenke 当我删除extern const
位并假设它是一个全局变量时,我得到了同样的错误。当我可以在标头中使用初始化程序时,我真的不想将定义放入源文件中。
@AndrewLalis 你不能。按照您编写的方式,每个源文件都隐含地获取了 numbers 数组的 定义。您应该在标头中声明该数组,并在一个源文件中定义它(不带 extern 关键字)。
@HellmarBecker 那么我是否应该在我的一个源中创建一个“init”函数来定义我需要的所有数组?
【参考方案1】:
根据C++ standard§3.1.2
声明是一个定义,除非它声明一个函数而不指定函数的主体,它包含 extern 说明符或链接说明,并且既不包含 初始化器也不是函数体...
头文件tengwarlibrary.h
中numbers
的声明是带有初始化器的外部声明。所以它也是一个定义。
由于您在两个源文件中包含了tengwarlibrary.h
(其中一个定义了translateFromTengwarToEnglish()
,一个定义了main()
),它们都具有numbers
的定义。因此,错误。
为了解决这个问题,在头文件中声明 number
和 extern
并在单个源文件中初始化它。
【讨论】:
以上是关于C++ 多个定义,即使只给出一个定义的主要内容,如果未能解决你的问题,请参考以下文章
即使使用 `-dec-math`,gfortran 也会对 `dacosd_` 给出未定义的引用