注册 登录  
 加关注
查看详情
   显示下一条  |  关闭
温馨提示!由于新浪微博认证机制调整,您的新浪微博帐号绑定已过期,请重新绑定!立即重新绑定新浪微博》  |  关闭

过☆客

一颗迷茫的心在3D世界中飘荡...

 
 
 

日志

 
 
关于我

爱宁静,不爱喧闹, 爱奋斗,也爱自由, 爱顺其自然,爱独来独往, 没高学历,不算成功, 没车也没房,但我真诚, 走进你的世界,却不留痕迹, 我是过客,不只是过客...

 
 

由内联函数引发的unresolved external symbol及inline  

2013-06-16 14:25:10|  分类: 日积月累-编程 |  标签: |举报 |字号 订阅

  下载LOFTER 我的照片书  |
平是在对于频繁执行的且函数体不是太复杂的函数,我们会用到内联,就在是函数申明的时候加个inline修饰。但在使用内联的时候一不小时就会遇到unresolved external symbol未定义的错误,这是我们写的内联函数与它本身的机制造成的。
内联运行机制及优点。内联函数的运行机制是在调用处展开函数体所有代码。由于中间过程省去了内存寻址/堆栈操作等费时的系统开销,显然,内联化的函数将可显著提高普通函数所执行效率的N个数量级。特别是在需要大量使用的场合中,是最佳化实施手段之一。
一、运行机制及优点
内联函数的运行机制是在调用处展开函数体所有代码。由于中间过程省去了内存寻址/堆栈操作等费时的系统开销,显然,内联化的函数将可显著提高普通函数所执行效率的N个数量级。特别是在需要大量使用的场合中,是最佳化实施手段之一。
二、类和内联函数
通常我们抽像一个类的步骤如下:
1、将需要抽像的类的声明(declaration)放在一个独立的*.h中;
2、将需要抽像的类的定义(definition)放在一个独立的*.cpp中(用cl.exe编译成一个独立的*.obj),由于该类是一个我们工程中很普通的成员,所以我们将它所有的成员函数内联化。
然后,当我们工程中的某个地方需要调用时,就在它源码(must be a *.cpp file)内的顶部以#include <*.h>方法将该类的*.h包含进来,以此declared info.来识别我们需要用到的symbol(标识符)。接着,我们就可以使用该类的类型。
三、类的实例化及将引发的unresolved external symbol错误及因和果
举例如下,假设我们已编写了一个String类,它的声明放在“String.h”,定义在“String.cpp”,然后我们在主程序文件“test.cpp”中调用:
-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-
#include <iostream>
#include "String.h"
int main()
{
String job( "Programmer" ), name( "dreamerate" );
cout << job << ": " << name << endl;
}
-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-
结果,出现如下错误:
-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-
test.obj : error LNK2001: unresolved external symbol "public: __thiscall String:
:~String(void)" (??1String@@QAE@XZ)
test.obj : error LNK2001: unresolved external symbol "public: char & __thiscall
String::operator[](int)" (??AString@@QAEAADH@Z)
test.obj : error LNK2001: unresolved external symbol "public: bool __thiscall St
ring::operator==(char const *)" (??8String@@QAE_NPBD@Z)
test.obj : error LNK2001: unresolved external symbol "public: bool __thiscall St
ring::operator==(class String const &)" (??8String@@QAE_NABV0@@Z)
test.obj : error LNK2001: unresolved external symbol "class ostream & __cdecl op
erator<<(class ostream &,class String const &)" (??6@YAAAVostream@@AAV0@ABVStrin
g@@@Z)
test.obj : error LNK2001: unresolved external symbol "class istream & __cdecl op
erator>>(class istream &,class String &)" (??5@YAAAVistream@@AAV0@AAVString@@@Z)
test.obj : error LNK2001: unresolved external symbol "public: __thiscall String:
:String(char const *)" (??0String@@QAE@PBD@Z)
test.obj : error LNK2001: unresolved external symbol "public: __thiscall String:
:String(void)" (??0String@@QAE@XZ)
String.exe : fatal error LNK1120: 8 unresolved externals
-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-
问题原因如下:由内联函数机制所知,我们都知道,它是在调用处展开函数体,由于这个展开过程是在cl.exe编译时进行的,又由于我们将调用处及类的文件分别单独编译,所以……将引发以上问题。
四、总结
内联函数只限出现在所编译依赖的目标文件(object file)中。所以当以inline来修饰一个在外部定义的类成员函数(class member functions)时,必须在调用处的源码中以#include方法加引进来。
要解决这个问题有二种办法
1) 将函数的实现写在*.h文件中
2) #include包含对应的*.cpp文件。如:
#include "String.cpp"  // #include "String.h" 改为#include "String.cpp"

本文参考 chenokay_新浪博客
  评论这张
 
阅读(633)| 评论(0)
推荐 转载

历史上的今天

在LOFTER的更多文章

评论

<#--最新日志,群博日志--> <#--推荐日志--> <#--引用记录--> <#--博主推荐--> <#--随机阅读--> <#--首页推荐--> <#--历史上的今天--> <#--被推荐日志--> <#--上一篇,下一篇--> <#-- 热度 --> <#-- 网易新闻广告 --> <#--右边模块结构--> <#--评论模块结构--> <#--引用模块结构--> <#--博主发起的投票-->
 
 
 
 
 
 
 
 
 
 
 
 
 
 

页脚

网易公司版权所有 ©1997-2018