我有一个主要由静态公共成员组成的类,因此我可以将仍然必须从其他类/函数调用的相似函数组合在一起。
无论如何,我在类公共作用域中定义了两个静态的无符号char变量,当我尝试在同一类的构造函数中修改这些值时,在编译时出现“无法解析的外部符号”错误。
class test
{
public:
static unsigned char X;
static unsigned char Y;
...
test();
};
test::test()
{
X = 1;
Y = 2;
}
我是C ++的新手,所以对我轻松一点。为什么我不能这样做?
#1 楼
如果您使用的是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文件中)中进行此操作
#2 楼
类声明中的静态数据成员声明不是它们的定义。要定义它们,应在
.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.
}
评论
为什么在.CPP中,它是“ unsigned char test :: X = 1;”而不是“ test :: X = 1;”?静态变量X已经定义,为什么还需要“ unsigned char”? @sergtk
–竹enny
18-09-18在22:56
@Penny因为“ test :: X = 1;”被解释为一项任务,而我们试图做的是一个定义。
–匿名1847
4月29日下午6:42
#3 楼
由于这是通常在搜索“带有静态const成员的未解决的外部对象”时出现的第一个SO线程,因此,我将在这里留下另一个提示来解决未解决的外部对象的问题:对我来说,我忘记的是标记我的类定义
__declspec(dllexport)
,当从另一个类(在该类的dll的边界之外)调用时,我当然会遇到我无法解决的外部错误。仍然,容易忘记当您将内部帮助程序类更改为可从其他地方访问的类时,因此,如果您正在动态链接的项目中工作,则最好也进行检查。
#4 楼
就我而言,我在.h文件中声明了一个静态变量,例如//myClass.h
class myClass
{
static int m_nMyVar;
static void myFunc();
}
,在myClass.cpp中,我尝试使用此m_nMyVar。出现类似LINK错误的错误:
错误LNK2001:未解决的外部符号“ public:静态类...
与链接错误相关的cpp文件如下:
所以我在myClass.cpp的顶部添加以下代码
//myClass.cpp
void myClass::myFunc()
{
myClass::m_nMyVar = 123; //I tried to use this m_nMyVar here and got link error
}
然后LNK2001不见了。
#5 楼
就我而言,我使用了错误的链接。它是用c ++(cli)管理的,但具有本机导出功能。我已向链接器->输入->程序集链接资源中添加了从中导出函数的库的dll。但是本机c ++链接需要.lib文件才能正确“查看” cpp中的实现,因此对我来说,这有助于将.lib文件添加到链接器->输入->其他依赖项。
[通常,托管代码不使用dll导出和导入,而是使用引用,但这是唯一的情况。]
评论
如果您正在编写仅标头库,则可以使用此技术来避免使用cpp文件:stackoverflow.com/questions/11709859/…
– Shital Shah
16年11月18日在18:49