【问题标题】:Undefined reference to a static member对静态成员的未定义引用
【发布时间】:2021-12-13 16:09:01
【问题描述】:

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

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++ undefined-reference cross-compiling


【解决方案1】:

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

LARGE_INTEGER WindowsTimer::_frequency;

【讨论】:

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

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

inline static LARGE_INTEGER _frequency;

【讨论】:

    【解决方案3】:

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

    更详细的解释here

    【讨论】:

      【解决方案4】:

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

      LARGE_INTEGER WindowsTimer::_frequency = 0;
      

      【讨论】:

        【解决方案5】:

        这是this other question 的完整代码示例,确实是这个的副本。

        #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;
        }
        

        【讨论】:

        • 感谢您的回答。你能否分享一个链接,我可以在其中阅读更多关于静态成员函数(重要)和静态变量(我已经看过很多)的信息。其中包含更多详细信息和静态函数示例以及类的伪造静态构造函数
        猜你喜欢
        • 2014-02-17
        • 2021-07-10
        相关资源
        最近更新 更多