147

很简单地说:

我有一个主要由静态公共成员组成的类,因此我可以将仍然必须从其他类/函数调用的类似函数组合在一起。

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

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

    ...

    test();
};

test::test() 
{
    X = 1;
    Y = 2;
}

我是 C++ 新手,所以请放轻松。为什么我不能这样做?

4

6 回答 6

166

如果您使用的是C++ 17,则可以只使用说明inline符(请参阅https://stackoverflow.com/a/11711082/55721


如果使用旧版本的 C++ 标准,则必须添加定义以匹配 X 和 Y 的声明

unsigned char test::X;
unsigned char test::Y;

某处。您可能还想初始化一个静态成员

unsigned char test::X = 4;

再一次,您在定义中(通常在 CXX 文件中)而不是在声明中(通常在 .H 文件中)执行此操作

于 2008-10-12T07:49:10.860 回答
72

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

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

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

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

test::test() {
}

如果您希望能够修改静态变量(换句话说,当不适合将它们声明为 const 时),您可以通过以下方式将代码分隔.H开来:.CPP

。H :

class test {
public:

  static unsigned char X;
  static unsigned char Y;

  ...

  test();
};

.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.
}
于 2008-10-12T08:26:29.757 回答
7

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

//myClass.h
class myClass
{
static int m_nMyVar;
static void myFunc();
}

在 myClass.cpp 中,我尝试使用这个 m_nMyVar。它得到了 LINK 错误,如:

错误 LNK2001: unresolved external symbol "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
}

所以我在 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
}

然后LNK2001就没了。

于 2018-09-18T23:35:41.177 回答
6

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

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

于 2018-05-04T07:37:40.833 回答
2

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

在下面的示例中,静态变量 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
于 2021-04-17T12:59:58.763 回答
0

就我而言,我使用了错误的链接。
它是托管的 c++ (cli),但具有本机导出功能。我已将导出函数的库的 dll 添加到链接器 -> 输入 -> 程序集链接资源中。但是本机 c++ 链接需要 .lib 文件才能正确“查看”cpp 中的实现,所以对我来说,帮助将 .lib 文件添加到链接器 -> 输入 -> 附加依赖项。
[通常托管代码不使用 dll 导出和导入,它使用引用,但这是独特的情况。]

于 2020-02-10T13:23:04.580 回答