我有以下课程:
MessageConstants.h:
class MessageConstants
{
public:
...
static const int ErrorDescriptionLength = 256;
...
};
SystemMessage.h:
class EvtError
{
private:
struct MsgData
{
int errorCode;
char errorDescription[MessageConstants::ErrorDescriptionLength];
}__attribute__((packed)) msgData;
public:
EvtError(int errorCode, string errorDescription);
inline void setErrorDescription(string desc){memcpy(msgData.errorDescription, desc.c_str(),
min(MessageConstants::ErrorDescriptionLength, (int)desc.length()));}
};
SystemMessage.cpp:
EvtError::EvtError(int errorCode, string errorDesc)
{
memset(&msgData, '\0', sizeof(msgData));
msgData.errorCode = errorCode;
memcpy(msgData.errorDescription, errorDesc.c_str(), min(MessageConstants::ErrorDescriptionLength, (int)errorDesc.length()));
}
我在 SystemMessage.cpp 声明memcpy(msgData.errorDescription, errorDesc.c_str(), min(MessageConstants::ErrorDescriptionLength, (int)errorDesc.length()));
上收到以下链接错误:
在函数EvtError :: EvtError(int,std :: string)中: 对MessageConstants :: ErrorDescriptionLength的未定义引用 collect2:错误:ld返回1退出状态 make:[link]错误1
如果我将MessageConstants::ErrorDescriptionLength
替换为sizeof(msgData.errorDescription)
,则链接错误消失。
我的问题:
为什么它不会抱怨 SystemMessage.h 文件中的MessageConstants::ErrorDescriptionLength
,其中有两个位置?
如何避免上述链接错误?
答案 0 :(得分:3)
min
的签名是:
template <typename T>
const T& min(const T&, const T&);
它通过引用获取输入 - 这需要它们具有存储空间。你的常数:
static const int ErrorDescriptionLength = 256;
目前没有存储空间。有两种方法可以解决这个问题。首先,您只需在.cpp中添加存储空间:
const int MessageConstants::ErrorDescriptionLength;
其次,您可以将其强制转换为int:
min((int)MessageConstants::ErrorDescriptionLength, (int)errorDesc.length())
// ^^^^^
答案 1 :(得分:0)
静态变量必须在类外部有定义:
const int MessageConstants::ErrorDescriptionLength ;
这应该只有一个.cpp
。文件在您的项目中。
有时你可以在没有它的情况下逃脱,但在这种情况下,要么是因为变量不是 odr-used ,要么程序形成不良(但是ODR违规不需要诊断)。