错误:(初始化数据项的非法重复定义)在C++;代码 我们试图在一个串联X系列机上编译一个程序,但是我们得到了形式错误,“C和/或C++中初始化数据项的非法重复定义”。同样的代码在aTandem S系列机器上为我们成功编译
我们有以下文件结构: /---地址映射----/ /*file2.cpp:->也使用AddressMap的第二个文件*/错误:(初始化数据项的非法重复定义)在C++;代码 我们试图在一个串联X系列机上编译一个程序,但是我们得到了形式错误,“C和/或C++中初始化数据项的非法重复定义”。同样的代码在aTandem S系列机器上为我们成功编译,c++,tandem,C++,Tandem,我们有以下文件结构: /---地址映射----/ /*file2.cpp:->也使用AddressMap的第二个文件*/ #include "AddressMap.h" // include file #include "AddressMap.h" // include file 问题 两个文件都已成功编译,但将它们链接在一起失败,原因是 初始化数据项的非法重复定义gAddressMap 在file1.o和file2.o中 由于两个文件都需要访问这个变量,所以都包含了头文件;也许
#include "AddressMap.h" // include file
#include "AddressMap.h" // include file
问题
两个文件都已成功编译,但将它们链接在一起失败,原因是
初始化数据项的非法重复定义gAddressMap
在file1.o和file2.o中
由于两个文件都需要访问这个变量,所以都包含了头文件;也许这就是错误的原因。而且,它是现有的代码,所以我们希望避免重大的代码更改。特别是,我们希望保持相同的头文件和变量名
我们如何解决这个错误
串联细节:
- X系列
- 使用的链接器是xld(nld在此系列中不可用)
extern
限定符声明全局变量,因为此全局变量在多个C文件中共享
extern gAddress gAddressMap; // define variable
在我看来,您应该在头文件中用
extern
限定符声明全局变量,因为这个全局变量在多个C文件中共享
extern gAddress gAddressMap; // define variable
每个编译单元——粗略地说,一个源文件和直接或间接包含在其中的所有文件——都是单独编译的。因此,如果您将特定的头包含到两个单独的文件中,那么这两个文件都会编译声明
gAddress::iterator gAddressIterator; // define iterator
gAddress gAddressMap; // define variable
由于这些对象未声明为外部对象,因此它们构成了这些对象的定义。因此,包含标头的每个文件都包含这些对象的定义,并且每个对象文件都有各自的版本。C++允许同一对象的多个声明,但在每个完整的程序中只有一个定义。因为您的每个模块都有一个gaddress映射
和gaddress迭代器
的定义,所以您无法形成一个将两者结合起来的一致性程序
解决方案分为两部分。首先,必须确保头文件的声明不是定义。您可以通过声明它们extern
来实现这一点:
extern gAddress::iterator gAddressIterator; // declare iterator
extern gAddress gAddressMap; // declare variable
第二,您必须将实际的定义放在某个地方,在所有要合并到一个程序中的文件中的某个文件中。如果有一个源文件包含用于初始化或以其他方式管理这些对象的函数,那么这将是一个很有希望的地方,但不是多个其他文件可能包含的头文件。每个编译单元——粗略地说,一个源文件和直接或间接包含在其中的所有文件是分开编译的。因此,如果您将特定的头包含到两个单独的文件中,那么这两个文件都会编译声明
gAddress::iterator gAddressIterator; // define iterator
gAddress gAddressMap; // define variable
由于这些对象未声明为外部对象,因此它们构成了这些对象的定义。因此,包含标头的每个文件都包含这些对象的定义,并且每个对象文件都有各自的版本。C++允许同一对象的多个声明,但在每个完整的程序中只有一个定义。因为您的每个模块都有一个gaddress映射
和gaddress迭代器
的定义,所以您无法形成一个将两者结合起来的一致性程序
解决方案分为两部分。首先,必须确保头文件的声明不是定义。您可以通过声明它们extern
来实现这一点:
extern gAddress::iterator gAddressIterator; // declare iterator
extern gAddress gAddressMap; // declare variable
第二,您必须将实际的定义放在某个地方,在所有要合并到一个程序中的文件中的某个文件中。如果有一个源文件包含用于初始化或以其他方式管理这些对象的函数,那么这将是一个很有希望的地方,但不是多个其他文件可能包含的头文件