静态类成员上未解析的外部符号

122 c++ static class members

非常简单地说:

我有一个主要由静态公共成员组成的类,所以我可以将类似的函数组合在一起,但仍然需要从其他类/函数中调用它们.

无论如何,我在我的类公共范围中定义了两个静态unsigned char变量,当我尝试在同一个类的构造函数中修改这些值时,我在编译时遇到"未解析的外部符号"错误.

class test 
{
public:
    static unsigned char X;
    static unsigned char Y;

    ...

    test();
};

test::test() 
{
    X = 1;
    Y = 2;
}
Run Code Online (Sandbox Code Playgroud)

我是C++的新手,所以对我很轻松.为什么我不能这样做?

Col*_*sen 137

您忘记添加定义以匹配您的X和Y声明

unsigned char test::X;
unsigned char test::Y;
Run Code Online (Sandbox Code Playgroud)

某处.您可能还想初始化静态成员

unsigned char test::X = 4;
Run Code Online (Sandbox Code Playgroud)

再次,你在定义中(通常在CXX文件中)不在声明中(通常在.H文件中)

  • 如果您正在编写仅限标头的库,则可以使用此技术来避免cpp文件:http://stackoverflow.com/questions/11709859/how-to-have-static-data-members-in-a-header-only -图书馆 (4认同)

ser*_*gtk 60

类声明中的静态数据成员声明不是它们的定义.要定义它们,您应该在.CPP文件中执行此操作以避免重复的符号.

您可以声明和定义的唯一数据是整数静态常量.(值enums也可以用作常数值)

您可能希望将代码重写为:

class test {
public:
  const static unsigned char X = 1;
  const static unsigned char Y = 2;
  ...
  test();
};

test::test() {
}
Run Code Online (Sandbox Code Playgroud)

如果你想有修改你静态变量的能力(换句话说,当它是不恰当的将它们声明为const),也可以分开你的代码之间.H,并.CPP以下列方式:

.H :

class test {
public:

  static unsigned char X;
  static unsigned char Y;

  ...

  test();
};
Run Code Online (Sandbox Code Playgroud)

.CPP:

unsigned char test::X = 1;
unsigned char test::Y = 2;

test::test()
{
  // constructor is empty.
  // We don't initialize static data member here, 
  // because static data initialization will happen on every constructor call.
}
Run Code Online (Sandbox Code Playgroud)


Pen*_*nny 9

就我而言,我在 .h 文件中声明了一个静态变量,例如

//myClass.h
class myClass
{
    static int m_nMyVar;
    static void myFunc();
}
Run Code Online (Sandbox Code Playgroud)

在myClass.cpp中,我尝试使用这个m_nMyVar。它出现 LINK 错误,例如:

错误 LNK2001: 无法解析的外部符号“public: static class... 与链接错误相关的 cpp 文件如下所示:

//myClass.cpp
void myClass::myFunc()
{
    myClass::m_nMyVar = 123; //I tried to use this m_nMyVar here and got link error
}
Run Code Online (Sandbox Code Playgroud)

所以我在 myClass.cpp 的顶部添加以下代码

//myClass.cpp
int myClass::m_nMyVar; //it seems redefine m_nMyVar, but it works well
void myClass::myFunc()
{
    myClass::m_nMyVar = 123; //I tried to use this m_nMyVar here and got link error
}
Run Code Online (Sandbox Code Playgroud)

然后LNK2001就消失了。


Joh*_*ski 6

由于这是我在搜索“具有静态常量成员的未解析外部对象”时似乎出现的第一个 SO 线程,因此我将在此处留下另一个提示来解决未解析外部对象的一个​​问题:

对我来说,我忘记的是标记我的类定义__declspec(dllexport),当从另一个类(在该类的 dll 边界之外)调用时,我当然得到了我未解决的外部错误。
尽管如此,当您将内部帮助类更改为可从其他地方访问的帮助类时,很容易忘记,因此如果您在动态链接的项目中工作,您也不妨检查一下。


小智 5

当我们在类中声明静态变量时,它被该类的所有对象共享。由于静态变量仅在它们从未被构造函数初始化时才被初始化。相反,静态变量应该仅使用作用域解析运算符 (::) 在类外部显式初始化一次。

在下面的示例中,静态变量 counter 是 Demo 类的成员。请注意它是如何在类外部显式初始化的,初始值 = 0。

#include <iostream>
#include <string>
using namespace std;
class Demo{
   int var;
   static int counter;

   public:
   Demo(int var):var(var){
      cout<<"Counter = "<<counter<<endl;
      counter++;
   }
};
int Demo::counter = 0;                 //static variable initialisation
int main()
{
   Demo d(2), d1(10),d3(1);
}

Output:
Count = 0
Count = 1
Count = 2
Run Code Online (Sandbox Code Playgroud)