C++常见错误大全(转)
添加时间:2013-7-31 点击量:
看了下总结,很是好,也是曾经本身碰到的一些题目。转自:http://blog.163.com/mageng11@126/blog/static/140808374201181735038428/
0. XXXX is not a class or namespace错误
最诡异的错误,提示意思很明显,说你写的名字既不是一个类也不是一个定名空间,固然我C++程度不是很高,但再笨拙也不至于连类的格局class MyClass{....};也写不熟悉打听吧,报此错误原因显然跟它没紧要,那又是怎么回事呢?
答案是:#include stdafx.h没放在代码最开首!!!
stdafx.h常识简单说一下:
所谓头文件预编译,就是把一个(Project)中应用的一些MFC 标准头文件(如Windows.H、Afxwin.H)预先编译,今后该编译时,不再编译这项目组头文件,仅仅应用预编译的成果。如许可以加快编译速度,节俭时候。
预编译头文件经由过程编译stdafx.cpp 生成,以名定名,因为预编译的头文件的后缀是“pch”,所以编译成果文件是projectname.pch。
没把:#include stdafx.h放在代码最开首会产生什么题目呢?编译器认为,所有在指令#include stdafx.h前的代码都是预编译的,它会跳过#includestdafx. h之前的指令,应用projectname.pch 编译这条指令之后的所有代码。是以,当然会呈现找不到类的错误了。
是以,所有的CPP 实现文件第一条语句都应当是:#include stdafx.h。
一.LINK2001错误:
此类错误VS给出提示但双击不会定位到失足地址,提示也莫名其妙,要究其原因排错
(1)error LNK2001: unresolved external symbol void __cdecl GameShutdown(void) (?GameShutdown@@YAXXZ)
原因:头文件(如main.h)声了然办法GameShutdown(),但main.cpp里没有实现它。
排错:在中搜“GameShutdown”,定位在哪个.h文件,再在对应的.cpp文件中添加实现办法。
(2)子类未实现父类纯虚函数错误:
D3DRenderer.obj : error LNK2001: unresolved external symbol public: virtual void __thiscall CD3DRenderer::SetMultiTexture(void) (?SetMultiTexture@CD3DRenderer@@UAEXXZ)
Debug/GameProject4.exe : fatal error LNK1120: 1 unresolved externals
原因:同上,在D3DRenderer.cpp(D3DRenderer.obj对应响应的.cpp)中未实现虚办法SetMultiTexture(),这个虚办法是在类的CD3DRenderer的父类中声明,虚办法必然要实现,不然会呈现unresolved externals错误
排错:简单,在类CD3DRenderer(D3DRenderer.cpp)中实现这个虚办法既可。
//C++ 子类没有实现父类的纯虚函数,则子类也变成抽象类,子类也不克不及实例化对象
/在设计基类的时辰不好断定将来的行动具体应当发挥解析什么行动,然则必须的。
含有纯虚函数的类叫抽象类。抽象类不克不及实例化它的对象,只能为它的派生类办事。
若是子类没有实现父类的纯虚函数,则子类也变成抽象类,它也不克不及实例化对象。
/
二、LINK2019 无法解析外部符号__declspec(dllimport)“的错误
错误 1 error LNK2019: 无法解析的外部符号 __declspec(dllimport) public: __thiscall CEGUI::OgreCEGUIRenderer::OgreCEGUIRenderer(class Ogre::RenderWindow ,unsigned char,bool,unsigned int,class Ogre::SceneManager ) (__imp_??0OgreCEGUIRenderer@CEGUI@@QAE@PAVRenderWindow@Ogre@@E_NIPAVSceneManager@3@@Z),该符号在函数 protected: virtual void __thiscall MouseQueryApplication::createScene(void) (?createScene@MouseQueryApplication@@MAEXXZ) 中被引用 SampleAPP.obj
经典的找不到dll错误,法度调用的办法在dll中定义,解决办法有两步:
1.找到此dll文件,还有对应的同名lib(若是是静态链接库),按照上述错误为OgreCEGUIRenderer开首的dll文件中,找到后放到你的工作空间(可能是\bin)目次下。
2.若是还是没有解决,那么必然是项目里没有引用响应的lib文件,因为别人的法度代码没有题目然则法度设置里添加了lib文件你可能没有设置,你可以在项目属性-》链接器-》输入-》附加依附项里添加响应的lib,或者一劳永逸的办法是在法度代码的开首(#include下面)指定:
#pragma comment(lib,CEGUIBase_d.lib)
这与在项目属性设置是一样的结果,然则会更夺目,第三方用户拷入你的代码不会再呈现找不到dll的错误
三、法度中读取磁盘碰到找不到,资料文件引起的错误,或调用某个错杂SDK函数失败返回
此类错误vs中不会给出提示,排错很艰苦,在编程时在可能失足的处所要养成多MessageBox的好习惯
不良写法 if(!m_Device) return; // 若是m_Device创建失败就返回,可是下面的代码不履行,这不是我们想要的
正确写法 if(!m_Device)
{
Messagebox(0, !m_Device, 0, 0); return; //这里可知道法度无故返回是因为m_Device创建失败造成的
}
四、法度中编译经由过程运行时却失足退出,警告框“某exe 在XXXXXX处呈现未处理惩罚的异常”
这是最难调的BUG,很多错误只有运行时才露出,这时须要借助VS中的客栈监控来查错。
例:运行时弹出 “couldnt add <id, 4002201> twice, Continue?”
点“否”让法度中断,VS弹出 Client.exe 在 XXXXXX处呈现未处理惩罚的异常,是否中断?点击中断。
这时打开“调用客栈”视窗,看到绿色箭头停在哪儿就是哪处所呈现的错误,然则一般它停的处所都是WIN API的低层,你是看不出来哪儿有题目,就向客栈底部找,就是向列表下面找,看是谁调用了失足的办法函数,一步一步找。这时我找到:
VarContain.Add(XX, XX) 看来是这儿加载时失足,某一关键字段加载了两次,但仍看不出哪儿反复加载,这时再向客栈底部找。
SkillProtoData->LoadFromFile(strFilename, .......) 看来是这儿加载文件有题目,用debug把守查看strFileName的文件名和路径,是“skillProtoName.xml”文件,去打开它,果真,文件里“id = 4002201”项有两条,删去一个反复项题目就解决了。
结论:当呈现“某exe 在XXXXXX处呈现未处理惩罚的异常”如许可骇错误时,客栈的帮助很首要!!!
四.error LNK2019: 无法解析的外部符号 _WinMain@16,该符号在函数 ___tmainCR...
一,题目描述
MSVCRTD.lib(crtexew.obj) : error LNK2019: 无法解析的外部符号 _WinMain@16,该符号在函数 ___tmainCRTStartup 中被引用
Debug\jk.exe : fatal error LNK1120: 1 个无法解析的外部号令
error LNK2001: unresolved external symbol _WinMain@16
debug/main.exe:fatal error LNK 1120:1 unresolved externals
error executing link.exe;
二,原因及解决办法
产生这个题目的真正原因是c说话运行时找不到恰当的法度进口函数,
一般景象下,若是是windows法度,那么WinMain是进口函数,在VS2008中新建项目为“win32项目”
若是是dos把握台法度,那么main是进口函数,在VS2008中新建项目为“win32把握台应用法度”
而若是进口函数指定不当,很显然c说话运行时找不到共同函数,它就会呈报错误。
批改设置适应你的需求
若是是windows法度:
1.菜单中选择 Project->Properties, 弹出Property Pages窗口
2.在左边栏中依次选择:Configuration Properties->C/C++->Preprocessor,然后在右边栏的Preprocessor Definitions对应的项中删除_COLE, 添加_WINDOWS.
3.在左边栏中依次选择:Configuration Properties->Linker->System,然后在右边栏的SubSystem对应的项改为Windows(/SUBSYSTEM:WINDOWS)
若是是把握台法度:
1.菜单中选择 Project->Properties, 弹出Property Pages窗口
2.在左边栏中依次选择:Configuration Properties->C/C++->Preprocessor,然后在右边栏的Preprocessor Definitions对应的项中删除_WINDOWS, 添加_COLE.
3.在左边栏中依次选择:Configuration Properties->Linker->System,然后在右边栏的SubSystem对应的项改为COLE(/SUBSYSTEM:COLE)
五、.exe 中的 0 x111552a1 处未处理惩罚的异常: 0 xC0000005: 读取地位 0 x00000018 时产生接见冲突
在Ogre::ResourceGroupManager::getSingleton().addResourceLocation( resource\gui.zip, Zip, GUI); 处法度中断
提示又是像外星文天书一般晦涩,看来排错成功迷茫。上彀查查看人家说,0 xC0000005一般默示空指针,加这里涉及到读取资料可以猜测可能路径不合错误。果本相对路径resource\gui.zip 改成绝对的d:\\gui.zip,就正常了,然则放在目次下还是有题目 ,那这个相对路径是相对哪儿的呢?工作空间莫非设置的有题目吗?
查“项目属性”->“调试”->工作空间 设置是“..\bin\Debug”, 退回上级目次进入此目次一看,果真没有“resource”文件夹。在此新建一个“resource”文件夹,再放一个“gui.zip”文件放进去,再编译,还是报错,细心搜检,改成“resource\\gui.zip”,成果终于编译成功了!
心得: 所谓工作空间就是相当于传统意义的文件夹,所以相对路径都是相对此目次的,而不是你想当然的法度目次。还有法度代码写路径时必然要双划线,切记!
六、error C2360: initialization of c is skipped by case label
void func( void )
{
int x;
switch ( x )
{
case 0 :
int i = 1; // error, skipped by case 1
{ int j = 1; } // ok, initialized in enclosing block
case 1 :
int k = 1; // ok, initialization not skipped
}
}
在switch语句内定义一个变量的时辰,若是不在一个语句块内,它是直到碰到switch的}才停止的。
所以,若是有在case内定义新变量,好将该条case内的语句加上{}构成语句块,避免失足
要么就不在case内定义变量,要定义全部case加上{}
七、“UINT WM_MY_REGISTERED_MSG” 已经在“XXX.obj”中定义
#pragma once不克不及解决头文件反复定义变量
咋一看,分明是UINT WM_MY_REGISTERED_MSG变量在XXX.cpp中反复定义了,可是搜遍全部,只发明 WM_MY_REGISTERED_MSG只在userMsg.h头文件中定义一处:UINT WM_MY_REGISTERED_MSG; 别处再无定义,这是怎么回事呢?
想起以前有位恩师反复告诉过我,头文件中只合适#define 常量和声明类和布局体的布局,不合适定义变量,要定义变量都要在.cpp中定义。那我尝尝把UINT WM_MY_REGISTERED_MSG放在主文件userMsg.cpp中,果真没错了。
看来是头文件多处包含惹的祸,固然头文件已经写了#pragma once能解决头文件反复包含,但不克不及解决反复定义变量。在一个头文件中定义了一个变量,哪怕是再不起眼的int n;只要这个头文件被多个cpp #include,那这个int n就算是反复定义,就会报XXX 已经在 XXX.obj中定义的怪现象。
结论:
头文件中只能声明布局,切切不成以定义变量!!!!
我所有的自负皆来自我的自卑,所有的英雄气概都来自于我的软弱。嘴里振振有词是因为心里满是怀疑,深情是因为痛恨自己无情。这世界没有一件事情是虚空而生的,站在光里,背后就会有阴影,这深夜里一片寂静,是因为你还没有听见声音。—— 马良《坦白书》
看了下总结,很是好,也是曾经本身碰到的一些题目。转自:http://blog.163.com/mageng11@126/blog/static/140808374201181735038428/
0. XXXX is not a class or namespace错误
最诡异的错误,提示意思很明显,说你写的名字既不是一个类也不是一个定名空间,固然我C++程度不是很高,但再笨拙也不至于连类的格局class MyClass{....};也写不熟悉打听吧,报此错误原因显然跟它没紧要,那又是怎么回事呢?
答案是:#include stdafx.h没放在代码最开首!!!
stdafx.h常识简单说一下:
所谓头文件预编译,就是把一个(Project)中应用的一些MFC 标准头文件(如Windows.H、Afxwin.H)预先编译,今后该编译时,不再编译这项目组头文件,仅仅应用预编译的成果。如许可以加快编译速度,节俭时候。
预编译头文件经由过程编译stdafx.cpp 生成,以名定名,因为预编译的头文件的后缀是“pch”,所以编译成果文件是projectname.pch。
没把:#include stdafx.h放在代码最开首会产生什么题目呢?编译器认为,所有在指令#include stdafx.h前的代码都是预编译的,它会跳过#includestdafx. h之前的指令,应用projectname.pch 编译这条指令之后的所有代码。是以,当然会呈现找不到类的错误了。
是以,所有的CPP 实现文件第一条语句都应当是:#include stdafx.h。
一.LINK2001错误:
此类错误VS给出提示但双击不会定位到失足地址,提示也莫名其妙,要究其原因排错
(1)error LNK2001: unresolved external symbol void __cdecl GameShutdown(void) (?GameShutdown@@YAXXZ)
原因:头文件(如main.h)声了然办法GameShutdown(),但main.cpp里没有实现它。
排错:在中搜“GameShutdown”,定位在哪个.h文件,再在对应的.cpp文件中添加实现办法。
(2)子类未实现父类纯虚函数错误:
D3DRenderer.obj : error LNK2001: unresolved external symbol public: virtual void __thiscall CD3DRenderer::SetMultiTexture(void) (?SetMultiTexture@CD3DRenderer@@UAEXXZ)
Debug/GameProject4.exe : fatal error LNK1120: 1 unresolved externals
原因:同上,在D3DRenderer.cpp(D3DRenderer.obj对应响应的.cpp)中未实现虚办法SetMultiTexture(),这个虚办法是在类的CD3DRenderer的父类中声明,虚办法必然要实现,不然会呈现unresolved externals错误
排错:简单,在类CD3DRenderer(D3DRenderer.cpp)中实现这个虚办法既可。
//C++ 子类没有实现父类的纯虚函数,则子类也变成抽象类,子类也不克不及实例化对象
/在设计基类的时辰不好断定将来的行动具体应当发挥解析什么行动,然则必须的。
含有纯虚函数的类叫抽象类。抽象类不克不及实例化它的对象,只能为它的派生类办事。
若是子类没有实现父类的纯虚函数,则子类也变成抽象类,它也不克不及实例化对象。
/
二、LINK2019 无法解析外部符号__declspec(dllimport)“的错误
错误 1 error LNK2019: 无法解析的外部符号 __declspec(dllimport) public: __thiscall CEGUI::OgreCEGUIRenderer::OgreCEGUIRenderer(class Ogre::RenderWindow ,unsigned char,bool,unsigned int,class Ogre::SceneManager ) (__imp_??0OgreCEGUIRenderer@CEGUI@@QAE@PAVRenderWindow@Ogre@@E_NIPAVSceneManager@3@@Z),该符号在函数 protected: virtual void __thiscall MouseQueryApplication::createScene(void) (?createScene@MouseQueryApplication@@MAEXXZ) 中被引用 SampleAPP.obj
经典的找不到dll错误,法度调用的办法在dll中定义,解决办法有两步:
1.找到此dll文件,还有对应的同名lib(若是是静态链接库),按照上述错误为OgreCEGUIRenderer开首的dll文件中,找到后放到你的工作空间(可能是\bin)目次下。
2.若是还是没有解决,那么必然是项目里没有引用响应的lib文件,因为别人的法度代码没有题目然则法度设置里添加了lib文件你可能没有设置,你可以在项目属性-》链接器-》输入-》附加依附项里添加响应的lib,或者一劳永逸的办法是在法度代码的开首(#include下面)指定:
#pragma comment(lib,CEGUIBase_d.lib)
这与在项目属性设置是一样的结果,然则会更夺目,第三方用户拷入你的代码不会再呈现找不到dll的错误
三、法度中读取磁盘碰到找不到,资料文件引起的错误,或调用某个错杂SDK函数失败返回
此类错误vs中不会给出提示,排错很艰苦,在编程时在可能失足的处所要养成多MessageBox的好习惯
不良写法 if(!m_Device) return; // 若是m_Device创建失败就返回,可是下面的代码不履行,这不是我们想要的
正确写法 if(!m_Device)
{
Messagebox(0, !m_Device, 0, 0); return; //这里可知道法度无故返回是因为m_Device创建失败造成的
}
四、法度中编译经由过程运行时却失足退出,警告框“某exe 在XXXXXX处呈现未处理惩罚的异常”
这是最难调的BUG,很多错误只有运行时才露出,这时须要借助VS中的客栈监控来查错。
例:运行时弹出 “couldnt add <id, 4002201> twice, Continue?”
点“否”让法度中断,VS弹出 Client.exe 在 XXXXXX处呈现未处理惩罚的异常,是否中断?点击中断。
这时打开“调用客栈”视窗,看到绿色箭头停在哪儿就是哪处所呈现的错误,然则一般它停的处所都是WIN API的低层,你是看不出来哪儿有题目,就向客栈底部找,就是向列表下面找,看是谁调用了失足的办法函数,一步一步找。这时我找到:
VarContain.Add(XX, XX) 看来是这儿加载时失足,某一关键字段加载了两次,但仍看不出哪儿反复加载,这时再向客栈底部找。
SkillProtoData->LoadFromFile(strFilename, .......) 看来是这儿加载文件有题目,用debug把守查看strFileName的文件名和路径,是“skillProtoName.xml”文件,去打开它,果真,文件里“id = 4002201”项有两条,删去一个反复项题目就解决了。
结论:当呈现“某exe 在XXXXXX处呈现未处理惩罚的异常”如许可骇错误时,客栈的帮助很首要!!!
四.error LNK2019: 无法解析的外部符号 _WinMain@16,该符号在函数 ___tmainCR...
一,题目描述
MSVCRTD.lib(crtexew.obj) : error LNK2019: 无法解析的外部符号 _WinMain@16,该符号在函数 ___tmainCRTStartup 中被引用
Debug\jk.exe : fatal error LNK1120: 1 个无法解析的外部号令
error LNK2001: unresolved external symbol _WinMain@16
debug/main.exe:fatal error LNK 1120:1 unresolved externals
error executing link.exe;
二,原因及解决办法
产生这个题目的真正原因是c说话运行时找不到恰当的法度进口函数,
一般景象下,若是是windows法度,那么WinMain是进口函数,在VS2008中新建项目为“win32项目”
若是是dos把握台法度,那么main是进口函数,在VS2008中新建项目为“win32把握台应用法度”
而若是进口函数指定不当,很显然c说话运行时找不到共同函数,它就会呈报错误。
批改设置适应你的需求
若是是windows法度:
1.菜单中选择 Project->Properties, 弹出Property Pages窗口
2.在左边栏中依次选择:Configuration Properties->C/C++->Preprocessor,然后在右边栏的Preprocessor Definitions对应的项中删除_COLE, 添加_WINDOWS.
3.在左边栏中依次选择:Configuration Properties->Linker->System,然后在右边栏的SubSystem对应的项改为Windows(/SUBSYSTEM:WINDOWS)
若是是把握台法度:
1.菜单中选择 Project->Properties, 弹出Property Pages窗口
2.在左边栏中依次选择:Configuration Properties->C/C++->Preprocessor,然后在右边栏的Preprocessor Definitions对应的项中删除_WINDOWS, 添加_COLE.
3.在左边栏中依次选择:Configuration Properties->Linker->System,然后在右边栏的SubSystem对应的项改为COLE(/SUBSYSTEM:COLE)
五、.exe 中的 0 x111552a1 处未处理惩罚的异常: 0 xC0000005: 读取地位 0 x00000018 时产生接见冲突
在Ogre::ResourceGroupManager::getSingleton().addResourceLocation( resource\gui.zip, Zip, GUI); 处法度中断
提示又是像外星文天书一般晦涩,看来排错成功迷茫。上彀查查看人家说,0 xC0000005一般默示空指针,加这里涉及到读取资料可以猜测可能路径不合错误。果本相对路径resource\gui.zip 改成绝对的d:\\gui.zip,就正常了,然则放在目次下还是有题目 ,那这个相对路径是相对哪儿的呢?工作空间莫非设置的有题目吗?
查“项目属性”->“调试”->工作空间 设置是“..\bin\Debug”, 退回上级目次进入此目次一看,果真没有“resource”文件夹。在此新建一个“resource”文件夹,再放一个“gui.zip”文件放进去,再编译,还是报错,细心搜检,改成“resource\\gui.zip”,成果终于编译成功了!
心得: 所谓工作空间就是相当于传统意义的文件夹,所以相对路径都是相对此目次的,而不是你想当然的法度目次。还有法度代码写路径时必然要双划线,切记!
六、error C2360: initialization of c is skipped by case label
void func( void )
{
int x;
switch ( x )
{
case 0 :
int i = 1; // error, skipped by case 1
{ int j = 1; } // ok, initialized in enclosing block
case 1 :
int k = 1; // ok, initialization not skipped
}
}
在switch语句内定义一个变量的时辰,若是不在一个语句块内,它是直到碰到switch的}才停止的。
所以,若是有在case内定义新变量,好将该条case内的语句加上{}构成语句块,避免失足
要么就不在case内定义变量,要定义全部case加上{}
七、“UINT WM_MY_REGISTERED_MSG” 已经在“XXX.obj”中定义
#pragma once不克不及解决头文件反复定义变量
咋一看,分明是UINT WM_MY_REGISTERED_MSG变量在XXX.cpp中反复定义了,可是搜遍全部,只发明 WM_MY_REGISTERED_MSG只在userMsg.h头文件中定义一处:UINT WM_MY_REGISTERED_MSG; 别处再无定义,这是怎么回事呢?
想起以前有位恩师反复告诉过我,头文件中只合适#define 常量和声明类和布局体的布局,不合适定义变量,要定义变量都要在.cpp中定义。那我尝尝把UINT WM_MY_REGISTERED_MSG放在主文件userMsg.cpp中,果真没错了。
看来是头文件多处包含惹的祸,固然头文件已经写了#pragma once能解决头文件反复包含,但不克不及解决反复定义变量。在一个头文件中定义了一个变量,哪怕是再不起眼的int n;只要这个头文件被多个cpp #include,那这个int n就算是反复定义,就会报XXX 已经在 XXX.obj中定义的怪现象。
结论:
头文件中只能声明布局,切切不成以定义变量!!!!