2

私が遭遇した LNK2005 エラーの原因を理解できません。クラス A があるとします。

ファイルああ:

    #ifndef A_H
    #define A_H

    class A{
    public:
        static foo(void);
    private:
        static bool m_someVar;
    };

    bool A::m_someVar = false;

    #endif

ファイル A.cpp:

    #include "A.h"

    void A::foo(){
        m_someVar = true;
    }

上記のコードでは LNK 2005 が発生しますが、次のコードでは発生しません。

ファイルああ:

    #ifndef A_H
    #define A_H

    class A{
    public:
        static foo(void);
    private:
        static bool m_someVar;
    };

    #endif

ファイル A.cpp:

    #include "A.h"

    bool A::m_someVar = false;

    void A::foo(){
        m_someVar = true;
    }

ガードが含まれているにもかかわらず、誰かがなぜこれが起こっているのか説明できますか? #pragma once も追加する必要がありますか?

前もって感謝します。

編集: コンパイル エラー: 「エラー LNK2005: "private: static bool GameManager::m_isGameOver" (?m_isGameOver@GameManager@@0_NA) already defined in Execution.obj"

4

2 に答える 2

3

インクルード ガード (#ifndef と #pragma の両方) はコンパイル ユニット全体では機能しません。これは、ヘッダー ファイルで何も定義してはならず、宣言するだけでよい理由の 1 つです。もちろん、テンプレートを除いて。

コンパイル単位は、1 つの .cpp ファイルと含まれるすべてのヘッダーです。各 .cpp は、中間段階のコードのバイナリ表現を含むオブジェクト ファイルを作成します。これがコンパイル段階です。これらのオブジェクト ファイルは、リンク段階でリンクされます。「float foo;」がある場合、各 .cpp は C++ で個別に処理されるため。header.hpp で、a.cpp と b.cpp の両方に header.hpp が含まれている場合、コンパイラは、アプリケーションの実行時にどの foo を意味するかをどのように認識しますか?

于 2014-03-26T15:16:06.777 に答える
1

クラス宣言内の「静的」変数は、実際には、そのクラスのスコープ内にある extern 変数の宣言です。すべての extern 変数と同様に、正確に 1 つのソース ファイルで定義する必要があります。そうしないと、リンカーはそれについて文句を言います。

おそらく、複数のソース ファイルから .h ファイルをインクルードするため、複数の定義があります。

于 2014-03-26T15:15:30.300 に答える