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;

コードの問題は、ヘッダー ガードとは関係ありません。ヘッダー ガードは、ヘッダーが各翻訳単位で 1 回だけ解析されるようにします。ヘッダー ガードがない場合、コンパイラエラーが発生します。たとえば、前処理後に同じ翻訳単位で複数回定義されたクラスなどをコンパイラが認識します。あなたの場合、エラーはリンカーエラーLNK2005であり、同じシンボルが複数の翻訳単位で定義されたことを意味します(あなたの場合、定義付きのヘッダーを含む各翻訳単位で)。

于 2013-02-13T14:38:33.200 に答える
6

グローバル変数がconst(*) でない場合、ヘッダー ファイルに配置して、複数の翻訳単位 (ファイル) に含めることはできません.cpp。そうしないと、プログラム内に同じシンボルの複数の定義が作成され、ODR ( One Definition Rule、C++11 標準の 3.2 項を参照) に違反し、リンカがそれについて文句を言うことになります。

extern共有ヘッダーで修飾子を使用して、変数の宣言のみを提供する必要があります。

extern int var;

次に、1 つの .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 に答える