MFC类静态CArray成员调用报LNK2001未解析外部符号如何解决?
静态CArray成员LNK2001错误解决方案
根本原因
C++语法要求:类内声明的静态成员变量仅属于声明,不会分配实际存储空间,必须在类外部的全局作用域完成一次定义,链接器才能找到对应的符号地址,否则就会抛出LNK2001未解析外部符号错误,和CArray存储的类型无关。你之前使用int类型CArray能正常运行,是因为你此前已经在类外完成了该静态成员的定义,不是int类型有特殊适配。
具体修复步骤
- 补充静态成员的全局定义
在WhiteBoard类对应的.cpp实现文件中,所有函数之外的全局作用域,添加静态成员的定义代码即可:
如果你保留存储WhiteBoard实例的写法:
// 放在WhiteBoard.cpp全局作用域,不要写在任何函数内部 CArray<WhiteBoard, WhiteBoard> WhiteBoard::test;
如果你已经改为继承BoardBoss、存储基类的写法,对应修改定义即可:
// 基类存储版本的定义 CArray<BoardBoss, BoardBoss> WhiteBoard::test;
- 优化CArray模板参数避免额外问题
CArray的第二个模板参数是元素传递的参数类型,直接用类类型会触发不必要的拷贝操作,存储自定义类时建议改为引用类型,如果是跟踪实例的场景更建议存储指针避免对象切片:
// 头文件类内的声明修改为存储基类指针,不会出现派生类对象切片问题 static CArray<BoardBoss*, BoardBoss*> test; // 对应的cpp中定义修改为 CArray<BoardBoss*, BoardBoss*> WhiteBoard::test; // tester方法对应调整 void tester() { test.Add(this); }
补充说明
去掉static关键字后正常运行的原因是:非静态成员变量属于每个类实例所有,实例创建时会自动分配对应存储空间,不需要额外全局定义,但非静态成员每个实例独立存储,自然无法满足全局跟踪所有类实例的需求。
内容的提问来源于stack exchange,提问作者BartBB
相关产品推荐
相关产品推荐

