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

一、运行机制及优点

内联函数的运行机制是在调用处展开函数体所有代码。由于中间过程省去了内存寻址/堆栈操作等费时的系统开销,显然,内联化的函数将可显著提高普通函数所执行效率的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;

}

-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-

编译以cl.exe的命令行方式进行如下步骤:

cl /nologo /ML /GX /O2 /c string.cpp

cl /nologo /ML /GX /O2 /c test.cpp

结果,出现如下错误:

-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-

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方法加引进来。^_^

附 最后补上纠正代码如下:

-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-

#include <iostream>

#include "String.cpp"  // #include "String.h" 改为#include "String.cpp"

int main()

{

String job( "Programmer" ), name( "dreamerate" );

cout << job << ": " << name << endl;

}

-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-

编译以cl.exe的命令行方式进行如下步骤:

cl /nologo /ML /GX /O2 /c test.cpp

 
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值