非常简单地说:
我有一个主要由静态公共成员组成的类,所以我可以将类似的函数组合在一起,但仍然需要从其他类/函数中调用它们。
无论如何,我在我的类公共范围中定义了两个静态unsigned char变量,当我尝试在同一个类的构造函数中修改这些值时,我在编译时遇到“未解析的外部符号”错误。
class test
{
public:
static unsigned char X;
static unsigned char Y;
...
test();
};
test::test()
{
X = 1;
Y = 2;
}
我是C ++的新手,所以对我很轻松。为什么我不能这样做?
答案 0 :(得分:131)
您忘记添加定义以匹配您的X和Y声明
unsigned char test::X;
unsigned char test::Y;
某处。您可能还想初始化静态成员
unsigned char test::X = 4;
再次,您在定义中(通常在CXX文件中)不在声明中(通常在.H文件中)
答案 1 :(得分:59)
类声明中的静态数据成员声明不是它们的定义。
要定义它们,您应该在.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.
}
答案 2 :(得分:3)
由于这是第一个在搜索“静态const成员未解析的外部”时似乎出现的SO线程,我将在此处留下另一个提示解决一个未解决的外部问题:
对我而言,我忘记的是标记我的类定义callee(data, (Predicate<SomeDataClass>) d -> d.getRandom() > 0.5);
,当从另一个类(在该类的dll的边界之外)调用时,我当然得到了我未解决的外部错误。
当你将内部助手类改为可从其他地方访问的类时,很容易忘记,所以如果你在动态链接的项目中工作,你也可以检查它。
答案 3 :(得分:1)
在我的情况下,我在.h文件中声明了一个静态变量,例如
//myClass.h
class myClass
{
static int m_nMyVar;
static void myFunc();
}
,在myClass.cpp中,我尝试使用此m_nMyVar。出现LINK错误,如:
错误LNK2001:无法解析的外部符号“ public:静态类... 与链接错误相关的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不见了。
答案 4 :(得分:1)
当我们在一个类中声明一个静态变量时,它被该类的所有对象共享。由于静态变量仅在它们从未被构造函数初始化时才被初始化。相反,静态变量应该只在类外使用范围解析运算符 (::) 显式初始化一次。
在下面的例子中,静态变量 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
答案 5 :(得分:0)
就我而言,我使用了错误的链接。
它使用c ++(cli)进行管理,但具有本机导出功能。我已向链接器->输入->程序集链接资源中添加了从中导出函数的库的dll。但是本机c ++链接需要.lib文件才能正确“查看” cpp中的实现,因此对我来说,这有助于将.lib文件添加到链接器->输入->其他依赖项。
[通常,托管代码不使用dll导出和导入,而是使用引用,但这是唯一的情况。]