未定义的静态成员引用

kak*_*ush 70 c++ cross-compiling undefined-reference

我正在使用交叉编译器.我的代码是:

class WindowsTimer{
public:
  WindowsTimer(){
    _frequency.QuadPart = 0ull;
  } 
private:
  static LARGE_INTEGER _frequency;
};
Run Code Online (Sandbox Code Playgroud)

我收到以下错误:

对WindowsTimer :: _ frequency'的未定义引用

我也尝试将其改为

LARGE_INTEGER _frequency.QuadPart = 0ull;
Run Code Online (Sandbox Code Playgroud)

要么

static LARGE_INTEGER _frequency.QuadPart = 0ull;
Run Code Online (Sandbox Code Playgroud)

但我仍然得到错误.

有谁知道为什么?

Ed *_*eal 88

您需要_frequency在.cpp文件中定义.

LARGE_INTEGER WindowsTimer::_frequency;
Run Code Online (Sandbox Code Playgroud)

  • @nowox 因为 C++ 不是 C#...静态数据成员基本上是一个全局变量,恰好位于其类的命名空间中。类定义中的*声明*就像全局变量的外部*声明*:它声明其存在、名称和类型,但不创建对象(因为这样,您将在每个文件中拥有一个对象,其中包含带有类定义的标头,与所需的相反)。相反,在其中一个 cpp 文件中恰好有该对象的*一个*定义,并且链接器将使用该名称将代码解析为该对象。 (5认同)
  • 我为什么要这样做呢? (2认同)
  • @nowox 因此,在 C++17 之前需要单独的对象定义的原因与 C++ 过时的构建范例有关:它使用 20 世纪 70 年代“翻译单元”(peprocessing 后的文件)的思想,这些单元被单独编译成稀疏的对象文件信息(例如,无类型信息等)。链接阶段与语言无关(例如,对 C++ 一无所知)并且与编译阶段分开。(CTD) (2认同)
  • (ctd) 相比之下,Java 或 C# 等环境会产生更多“语义丰富”的编译工件(类、包),通常同时来自多个源文件:编译和链接没有明确分开,这允许不同文件中的代码之间更好的交互。 (2认同)

Vyk*_*tor 29

链接器不知道在哪里分配数据_frequency,你必须手动告诉它.您可以通过简单地将此行添加LARGE_INTEGER WindowsTimer::_frequency = 0;到您的一个C++源中来实现此目的.

这里有更详细的解释


Rag*_*ram 19

如果在类中声明了一个静态变量,那么你应该像这样在cpp文件中定义它

LARGE_INTEGER WindowsTimer::_frequency = 0;
Run Code Online (Sandbox Code Playgroud)


Zhe*_*Hao 12

使用C ++ 17,您可以声明inline变量,而无需再在cpp文件中定义它。

inline static LARGE_INTEGER _frequency;
Run Code Online (Sandbox Code Playgroud)

  • NVM,我刚刚通过MinGW Manager将我的GCC从6.3更新到了8.2,并且工作正常。 (2认同)