C ++链接器奇怪的行为:静态成员变量

时间:2018-01-26 16:09:02

标签: c++ linker

我遇到了链接器错误,需要一些帮助。我正在使用MSVC。

一开始,我做了这个:

/* graphics_app.h */
#ifndef DK_GRAPHICS_APP_H
#define DK_GRAPHICS_APP_H
...
class GraphicsApp {
private:
    static GraphicsApp* self;
...
};

GraphicsApp* GraphicsApp::self = nullptr;
#endif /* DK_GRAPHICS_APP_H */

此标头用于工作......我做了一些改进,但没有关于该静态成员的更改。

但出乎意料地我收到了此链接器错误消息:

LNK2005 "private: static class GraphicsApp * GraphicsApp::self" (?self@GraphicsApp@@0PEAV1@EA) already defined in main.obj.
LNK1169 one or more multiply defined symbols found.

所以,我把这个标题分成了.h和.cpp:

/* graphics_app.cpp */
#include "graphics_app.h" 
...
GraphicsApp* GraphicsApp::self = nullptr;

但我又收到了一个错误:

LNK2001 "private: static class GraphicsApp * GraphicsApp::self" (?self@GraphicsApp@@0PEAV1@EA) unresolved external symbol.
LNK1120 1 unresolved externals.

为什么会发生这些奇怪的行为?我该如何解决?

编辑:

我制作测试版本让问题变得简单。 当我使用自定义include目录时会发生这种情况...... 比如

#include <dk/graphics_app.h>

而不是

#include "graphics_app.h"

所以..一个新问题是,如何在使用我的自定义include目录时解决这个问题?

EDIT2:

让事情变得更加简单.. enter image description here

2 个答案:

答案 0 :(得分:0)

LNK2005: 发生此错误的原因是,头文件包含在另外两个cpp文件中(编译为obj文件)。然后当链接器试图链接obj时,它发现了两个相同的定义。但“只能有一个”!

由于这种模糊性,链接器放弃了。

LNK2001: 发生此错误是因为链接器未在任何obj文件中找到已定义的变量。所以我认为你的项目定义中缺少新的cpp。

答案 1 :(得分:0)

  

此标头用于工作......我做了一些改进,但没有关于该静态成员的更改。

您的标题写错了:您不应该将具有外部链接的实体的定义放入标题文件中。它可以&#34;工作&#34;只要您将头文件包含在一个且只有一个翻译单元中。但是,一旦将其包含在两个或更多不同的翻译单元中,您就可以获得多个定义&#34;错误。这正是你案件中发生的事情。

  

所以,我把这个标题分成了.h和.cpp

这是正确的做法。现在你必须确保你的graphics_app.cpp被编译(和链接)作为你的程序的一部分。这是你忘记做的事情。编译器/链接器/构建系统不能以某种方式&#34;神奇地&#34;我自己意识到你新创建的graphics_app.cpp应该是你项目的一部分。