C++头文件包含导致无法解析的外部符号问题

【问题背景】

任务:

C++实现文件拷贝,要求有界面输入源文件地址和目标文件地址,点击一个按钮将源文件夹下的全部都拷贝的目标文件夹下,另外最后的.exe要可以在cmd中输入两个参数实现同样的文件拷贝

实现:

界面用Qt事件,写一个copyFile函数有两个参数src和dst,点击按钮事件会调用copyFile函数并将界面获取的路径传入完成拷贝,main函数也接收参数,所以如果接收到说明用户用cmd方式传参,那么直接调用写好的copyFile函数完成,如果没有说明用户点击了.exe则用弹出窗口输入的方式。考虑到copyFile函数复用性以及文件操作的扩展性所以建了一个类叫fileOperator,想着以后可以写关于文件的其他操作,现在就简单的一个public的copyFile函数。OK,后来问题就出现了无法解析的外部符号

【问题原因及解决】

然后搜发现了参考中的那篇,我想复现之前的错误但是不知道为什么复现不了,所以把那篇文章中有用的摘一下

出现这个错误的错因大多数在于:

[0]出现无法解析可能是因为lib文件不正确,比如64位的编译配置,结果使用的是32位的lib包. 
[1]只写了类声明,但还没有写实现类,造成调用时无法解析 [2]声明和定义没有统一,造成链接不一致,无法解析 
[3]没有在项目属性页的链接器的命令行选项加入相应的类包。 [4]没有在c++包含目录和库目录加入相应的类包路径 
[5]在测试工程中被测文件目录可能需要包含被测类的cpp定义文件 
[6]ICE接口测试时,无法解析可能因为被测文件没有包含进相关的cpp文件,另外,在TestSuite_ProjectRun.h文件中需要包含IProjectRun.h头文件,及相关的头文件(举例)。 
[7]import相关的无法解析内容,解决办法是在链接器的依赖项中加入相应的动态库 [8]出现如下错误的原因一般是动态库没有包进来。 
[9]error LNK2001: 无法解析的外部符号 __imp___CrtDbgReportW 
工程属性,C/C++,代码生成,运行时库选择MDd,

无法解析的外部符号这个错误出现的问题可以归结为:编译器在使用某个函数或类时无法得到该函数或类的具体实现。而我的程序中调用库的函数仅有一两个,且系统的错误提示中是我编写的类中的函数无法解析。

实际中编码设计过程中,最基本的一个原则就是在类的头文件中最好不要包含其他头文件,因为这样会使类之间的文件包含关系变得复杂化。要最大限度的遵守这个原则,实际编码设计过程可以采用以下两种方法:

方法一是在设计一个类的时候尽量保持类的独立性,即使该类尽可能不要依赖其他类库或者函数库,或者退一步来说,尽量不要在类的声明中依赖其他类。这样,在 该类的声明头文件中就可以没有其他头文件。如果实现中用到了其他的类,那么可以只在该类的实现文件中包含用到的类库或者函数库的头文件就行。

方法二是当类的声明中必须得用到其他类库或者函数库时,方法一便不再适用,当一个类声明中引用的是其他类或结构的指针引用或者是函数引用时,也可以保持上 
述原则,做法是采用前向引用,及在该类的声明前面先声明一下该类所用到的类名或者函数名就行。当类声明中引用的是其他类的实例时,上述原则变不能保持,只 
有在该类的声明头文件中引用所引用的类库或者函数库的头文件。

看了那个博主写的,我的也是用了自定义类的对象,而不是指针,(不过我的类对象并不是类成员只是一个方法里面用到而已)但是头文件包含又混乱,所以导致编译器没编译部分头文件或无法找到与头文件相关的cpp文件

要注意的是一些头文件也有依赖关 系,这些文件的包含顺序也小心,否则就会出错。ps,头文件的包含顺序应该是从最特殊到一般,比如:我们应该以这样的方式来#include头文件: 
从最特殊到最一般,也就是

#include "本类头文件"
#include "本目录头文件"
#include "自己写的工具头文件"
#include "第三方头文件"
#include "平台相关头文件"
#include "C++库头文件"
#include "C库头文件"

【后记】

我本来想复现原来的问题,再记录一下的,但是又按原来的写竟然没有报错,所以我不知道原来的错误原因是不是这个,也可能是我复现的时候忘记之前写错的一些东西,总之都没报错,不过关于头文件包含关系以及使用之前还是很不清楚的,正好记录一下

【参考】

C++:无法解析的外部符号问题 与 头文件包含注意要点

 

你可能感兴趣的:(c++)