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 吗?

提前致谢。

编辑:这里是编译错误:“错误 LNK2005:“private: static bool GameManager::m_isGameOver”(?m_isGameOver@GameManager@@0_NA) 已经在 Execution.obj 中定义”

4

2 回答 2

3

包含守卫(#ifndef 和#pragma)不能跨编译单元工作,这是你永远不应该在头文件中定义任何东西的原因之一,只声明它们。当然,模板除外。

一个编译单元是一个 .cpp 文件和所有包含的头文件。每个 .cpp 创建一个包含代码的中间阶段二进制表示的目标文件,这是编译阶段。然后在链接阶段将这些目标文件链接在一起。因为如果你有“float foo;”,每个 .cpp 都在 C++ 中单独处理。在 header.hpp 和 a.cpp 和 b.cpp 都包含 header.hpp 中,编译器如何知道您在运行应用程序时指的是哪个 foo?

于 2014-03-26T15:16:06.777 回答
1

类声明中的“静态”变量实际上是该类范围内的外部变量的声明。像每个外部变量一样,它需要在一个源文件中进行定义。否则,链接器会抱怨它。

您可能包含来自多个源文件的 .h 文件,因此您有多个定义。

于 2014-03-26T15:15:30.300 回答