我想在代码中避免使用#defines。因此,我在头文件中有以下内容:
#ifndef __GATENAMES__
#define __GATENAMES__
namespace GateNames
{
const char* CBSD_GATE_TO_SAS = "CbsdGate_SAS_INOUT";
const char* CBSD_GATE_TO_SAS_OUT = "CbsdGate_SAS_INOUT$o";
const char* CBSD_GATE_TO_SAS_IN = "CbsdGate_SAS_INOUT$i";
const char* SAS_GATE_TO_CBSD = "SasGate_CBSD_INOUT";
const char* SAS_GATE_TO_ESC = "SasGate_ESC_INOUT";
const char* SAS_GATE_TO_ESC_OUT = "SasGate_ESC_INOUT$o";
const char* SAS_GATE_TO_ESC_IN = "SasGate_ESC_INOUT$i";
};
#endif
此头文件包含在我的代码中的各个位置。但是,链接器抱怨符号是多重定义的:
../out/gcc-debug/src/CbsdSim.o:(.data.rel.local+0x0): multiple definition of `GateNames::CBSD_GATE_TO_SAS'
如何解决这个问题?感谢。
答案 0 :(得分:5)
首先,像__GATENAMES__
这样的名称(任何以下划线和大写字母开头或包含两个连续下划线的名称)都是为C ++实现保留的 - 你不应该在自己的代码中创建这样的名字。
其次,你的常数有点混乱,而不是像:
const char* CBSD_GATE_TO_SAS = "CbsdGate_SAS_INOUT";
你想要:
const char * const CBSD_GATE_TO_SAS = "CbsdGate_SAS_INOUT";
换句话说,它的指针必须是const来限制指针的链接,而不是指向的东西(尽管在这种情况下也必须是const)。 / p>
答案 1 :(得分:1)
链接器错误的原因是非const变量具有外部链接,并且由于您在多个转换单元中定义它们(通过包含标头),链接器会抱怨。
有三种方法可以修复您的代码。首先是通过使它们成为静态来更改const char*
字符串文字的链接。这样他们就有内部联系,每个包含它们的翻译单元都不会与其他翻译单元共享 - 所以链接器也不会抱怨:
static const char* CBSD_GATE_TO_SAS = "CbsdGate_SAS_INOUT";
^^^^^^
第二个是使它们成为const:
const char* const CBSD_GATE_TO_SAS = "CbsdGate_SAS_INOUT";
^^^^^
实际上非常类似于使它们静止,它们现在具有内部链接。
第三种方法是在头文件中声明它们并在一个单独的翻译单元中定义:
// in header file
namespace GateNames
{
extern const char* CBSD_GATE_TO_SAS ;
};
在一些.cpp文件中:
namespace GateNames
{
const char* CBSD_GATE_TO_SAS = "CbsdGate_SAS_INOUT";
};