6

我有一个 MFC 应用程序 AVT_testapp,在头文件 (AVT_testappDlg.h) 中,我试图在所有函数、类等之外创建一个变量,以使其成为全局变量。每当我尝试这样做时(比如我尝试int x = 7),我都会收到错误消息:

1>AVT_testappDlg.obj : error LNK2005: "int x" (?x@@3HA) already defined in 
    AVT_testapp.obj
1>..\..\bin\x64\Debug\AVT_testapp.exe : fatal error LNK1169: one or more 
    multiply defined symbols found

我在谷歌上找到的所有内容都说“只需添加标题保护”。 AVT_testappDlg 有 6 个#include,每个都有标头保护。

创建全局变量时,还有什么可能导致这些错误?

编辑:这是我的头文件的开头,

#pragma once

#include "../../src/CoreUtils/nierr.h"
#include "..\..\src\CoreUtils\StringHelpers.h" //includes windows.h
#include "afxwin.h"
#include "afxcmn.h"
#include "IFrameObserver.h"
#include "c:\Program Files (x86)\Microsoft SDKs\Windows\v7.0A\Include\GdiPlusHeaders.h"
//#include <fstream>
//#include <windows.h>

int x = 7;

using namespace AVT::VmbAPI;


//////////////////////////////////////////////////////////////////////////
//////////  MyObserver class   ///////////////////////////////////////////
//////////////////////////////////////////////////////////////////////////
class MyObserver : public IFrameObserver
{
private:
    MyObserver( MyObserver& );

    MyObserver& operator=( const MyObserver& );    

public:

    VmbUchar_t* imageData;

            //...
            //...
            //...
            //...

//that's the end of the relevant stuff
4

3 回答 3

12

您不能在标题中的命名空间级别定义变量。一般来说,最好不要有全局变量,但如果需要,您应该只在标头中提供声明,并在单个 .cpp 中提供定义:

//header
extern int i;

//cpp
int i;

您的代码问题与标头保护无关。标头保护确保标头在每个翻译单元中仅解析一次。缺少标头保护会导致编译器错误,例如编译器会在预处理后看到在同一个翻译单元中多次定义的类,例如一个类。在您的情况下,错误是链接器错误LNK2005,这意味着在多个翻译单元中定义了相同的符号(在您的情况下,在每个翻译单元中都包含带有定义的标题)。

于 2013-02-13T14:38:33.200 回答
6

如果全局变量不是const(*),则不能将其放在头文件中,并将其包含在多个翻译单元(即.cpp文件)中。否则,您最终将在程序中对同一符号进行多个定义,这违反了ODR一个定义规则,请参阅 C++11 标准的第 3.2 段),并且链接器会抱怨这一点。

您应该extern在共享标头中使用修饰符来仅提供变量的声明:

extern int var;

然后,在一个 .cpp文件中,您可以为其提供定义:

int var;

(*)const全局变量默认具有内部链接,因此每个翻译单元最终都会拥有它的私有副本,并且不会发生多重定义。

于 2013-02-13T14:38:47.030 回答
1

如果你坚持要有一个全局变量,至少把它放在一个命名空间中以避免与其他模块发生冲突

namespace globals
{
  extern int x;
}

然后在 .cpp 文件中定义它。

int globals::x = 0;

它也更清楚地表明它是一个全局变量。

于 2013-02-13T15:07:32.027 回答