为什么它在cpp文件中而不是在头文件中抱怨?

时间:2015-01-25 02:50:15

标签: c++

我有以下课程:

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),则链接错误消失。

我的问题:

  1. 为什么它不会抱怨 SystemMessage.h 文件中的MessageConstants::ErrorDescriptionLength,其中有两个位置?

  2. 如何避免上述链接错误?

2 个答案:

答案 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违规不需要诊断)。