对静态成员的未定义引用

Undefined reference to a static member

提问人:kakush 提问时间:2/2/2012 最后编辑:Raktim Biswaskakush 更新时间:6/30/2021 访问量:111260

问:

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

class WindowsTimer{
public:
  WindowsTimer(){
    _frequency.QuadPart = 0ull;
  } 
private:
  static LARGE_INTEGER _frequency;
};

我收到以下错误:

对“WindowsTimer::_frequency”的未定义引用

我也试着把它改成

LARGE_INTEGER _frequency.QuadPart = 0ull;

static LARGE_INTEGER _frequency.QuadPart = 0ull;

但我仍然遇到错误。

有人知道为什么吗?

C++ 未定义引用 交叉编译

评论

1赞 iammilind 2/2/2012
静态成员的未定义引用的可能重复,链接器错误
0赞 CB Bailey 2/2/2012
您在哪里(如果有的话)定义过?WindowsTimer::_frequency
0赞 kakush 2/2/2012
@CharlesBailey这是我班上唯一的成员。

答:

155赞 Ed Heal 2/2/2012 #1

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

LARGE_INTEGER WindowsTimer::_frequency;

评论

6赞 nowox 10/9/2020
我为什么要这样做?
19赞 Peter - Reinstate Monica 3/22/2021
@nowox 因为C++不是 C#...静态数据成员基本上是一个全局变量,恰好位于其类的命名空间中。类定义中的声明类似于全局变量的外部声明:它宣布它的存在、名称和类型,但不创建对象(因为这样一来,每个文件中都会有一个对象,其中包含带有类定义的标头,这与期望的相反)。相反,在其中一个 cpp 文件中只有一个该对象的定义,链接器会使用该名称将代码解析为该对象。
3赞 Peter - Reinstate Monica 3/22/2021
@nowox 因此,在 C++17 之前需要单独的对象定义的原因与过时的 C++ 构建范式有关:它使用了 1970 年代的“翻译单元”(经过处理后的文件)的概念,这些单元被单独编译为具有稀疏信息(例如,没有类型信息等)的目标文件。链接阶段与语言无关(例如,对 C++ 一无所知),并且与编译阶段分开。(CTD.)
3赞 Peter - Reinstate Monica 3/22/2021
(CTD)相比之下,像 Java 或 C# 这样的环境会生成更多“语义丰富”的编译工件(类、包),通常同时来自多个源文件: 编译和链接没有明确分开,这使得不同文件中的代码之间可以更好地交互。
1赞 Silidrone 7/29/2022
@Peter-恢复莫妮卡,我认为您的评论应该添加到答案中。
44赞 Vyktor 2/2/2012 #2

链接器不知道将数据分配到何处,您必须手动告诉它。您可以通过简单地将此行添加到其中一个 C++ 源代码中来实现此目的。_frequencyLARGE_INTEGER WindowsTimer::_frequency = 0;

更详细的解释在这里

29赞 Raghuram 2/2/2012 #3

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

LARGE_INTEGER WindowsTimer::_frequency = 0;
71赞 betteroutthanin 12/10/2018 #4

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

inline static LARGE_INTEGER _frequency;
4赞 Serge Ballesta 6/30/2021 #5

这是另一个问题的完整代码示例,它确实是这个问题的重复项。

#include <iostream>

#include <vector>
using namespace std;

class Car
{

public:
    static int b;                   // DECLARATION of a static member


    static char* x1(int x)
    {
        b = x;                      // The static member is used "not as a constant value"
                                    //  (it is said ODR used): definition required
        return (char*)"done";
    }

};

int Car::b;                         // DEFINITION of the static 

int main()
{
    char* ret = Car::x1(42);
    for (int x = 0; x < 4; x++)
    {
        cout << ret[x] << endl;
    }

    return 0;
}

评论

0赞 user786 6/30/2021
谢谢你的回答。你能分享一个链接吗,我可以在其中阅读更多关于静态成员函数(重要)和静态变量的信息(我已经见过很多次了)。这包含了静态函数的更多细节和示例,以及类</b 的 <b>faking 静态构造函数>
0赞 Sahil Tah 6/14/2022
@user786 您可以参考 YT 上切尔诺的这个视频链接