inline与lnk2001、lnk2019,鸡肋?
inline函数居然出现了lnk2001、lnk2019,先贴代码。
a.h
#pragma once
class A
{
public:
inline void foo();
void use_foo();
};
a.cpp
#include "A.h"
inline void A::foo()
{
}
void A::use_foo()
{
foo();//此行注释掉会产生lnk2019错误
}
main.cpp
#include "A.h"
int main()
{
A a;
a.foo();
return 0;
}
看似简单的程序,揭示出inline的使用限制:
1、在头文件中,类成员函数声明为inline时实现函数体,比如:
#pragma once
class A
{
public:
inline void foo(){};//实现了函数体即便是空的
void use_foo();
};
2、在头文件和源文件中分开实现,此类源文件中的“任意非inline函数续”需调用过此函数,然后其他源文件中才可用,此时链接时不会出现lnk2001 lnk2019错误。
如:上面的a.cpp
两种方法:
第一种缺点是破坏封装,生成的库拿给别人用总不希望被看到函数体的实现吧
第二种封装性好,别人只能看到声明,缺点是容易产生lnk错误。
其实编译器尽量把头文件中的带实现的函数优化为inline,只要不带循环之类的就可以不用声明inline。
inline只有在达到一定调用频率量级上才会显得快。比如:Release编译 /O2开启,第一种10亿次循环调用的差距大概在几十毫秒。第二种反而比非inline慢几到十几毫秒。
结论:inline没必要使用
如果是在头文件中实现类函数体,inline关键字不必使用,因为编译器默认会将头文件实现的类函数尽量优化为inline,而且这种破坏封装性,如果是编译给别人用的库还是算了。
如果是在源文件中实现类函数体,inline关键字不能用,因为你不能保证该源文件一定需要调用该函数,可能造成其它源文件的lnk2001 lnk2019链接错误。
如果追求极致性能又怕编译器不靠谱,请在头文件中声明inline且同时实现函数体,即便如此,编译器也会考量是否可编译为inline函数,并且前提是优化选项开启,比如VS的 /O2、g++的 -O2
本人仅在vs2012 release下做过简单测试,欢迎交流。
inline与lnk2001、lnk2019,鸡肋?的更多相关文章
- C++链接器工具错误:LNK2001, LNK2019(转载)
这是归属于链接器工具错误 这一类. 无法解析的外部符号“symbol” 代码引用了链接器无法在库和对象文件中找到的内容(如函数.变量或标签). 可能的原因 代码请求的内容不存在(例如,符号拼写错误或使 ...
- vs2010 在64bits系统下编译
vs只有32bits的没有64bits. 本来程序没问题,后面一直报错 LIBCMTD.lib(close.obj) : error LNK2001 LNK2019 换了各种 MD/MT/MTD 都没 ...
- VS2015生成64位dll文件
导入自己的源文件,准备生成DLL文件.也可以自己创建. 右键项目,进入属性,修改Configuration Type 为 DLL. 修改为64位,Configureation Manager -> ...
- 解决PCL MLS : error LNK2019; error LNK2001 virtual MovingLeastSquares process performProcessing问题
PCL 基于多项式拟合的法线估计.点云平滑和数据重采样 在使用Window VS2010为开发平台,学习PCL点云库的时候,学到曲面重建(Surface).在测试下面的程序的时候,遇到了问题. #in ...
- error LNK2019: unresolved external symbol / error LNK2001: 无法解析的外部符号
在 vc++ 2008 和 vc++ 2010 编译时分别出现上面的错误.一般这种错误是由于引用函数未定义造成的,如外部类库未包含,实现代码未编写等. 但最终检查的结果,却是另外一种情况:文件名重名. ...
- [C++] 烦人的error LNK2019和error LNK2001
常见原因: 没有正确的设置引用的lib,新手常犯这个错误,这是最容易解决的问题. extern "C"的问题.如果C++写的dll要给C程序用,那么就要注意extern " ...
- 摘:"error LNK2019: 无法解析的外部符号 该符号在函数 中被引用" 错误原因
例如“error LNK2019: 无法解析的外部符号error LNK2001: 无法解析的外部符号“private: static struct _OVERLAPPED CUsbCom::g_Wr ...
- vs LNK2019 无法解析的外部符号 ***,该符号在函数 WinMain 中被引用
一般链接错误都是因为包含头文件与lib库不匹配(无导出函数.lib库的release debug版本混乱.库引用的优先级.编译器设置mt/mtd等等)造成的. 错误 LNK2019 无法解 ...
- “error LNK2019: 无法解析的外部符号”之分析
最近在用VS 2008开发,初学遇到不少问题,最头疼的问题之一就是:LNK2019. 百度一下讲的并不够全面,反正都没解决我的问题. error LNK2019问题在VC 6.0中是error LNK ...
随机推荐
- VMware Workstation下VMnet1等虚拟网卡与主机网卡之间的关系
VMware Workstation下VMnet1等虚拟网卡与主机网卡之间的关系 本文出自 "王春海的博客" http://wangchunhai.blog.51cto.com/2 ...
- BZOJ 2510: 弱题( 矩阵快速幂 )
每进行一次, 编号为x的数对x, 和(x+1)%N都有贡献 用矩阵快速幂, O(N3logK). 注意到是循环矩阵, 可以把矩阵乘法的复杂度降到O(N2). 所以总复杂度就是O(N2logK) --- ...
- Python 第三篇(下):collections系列、集合(set)、单双队列、深浅copy、内置函数
一.collections系列: collections其实是python的标准库,也就是python的一个内置模块,因此使用之前导入一下collections模块即可,collections在py ...
- 用css实现列表菜单的效果
<!doctype html> <html lang="en"> <head> <meta charset="UTF-8&quo ...
- Java的位运算符具体解释实例——与(&)、非(~)、或(|)、异或(^)
位运算符主要针对二进制,它包含了:“与”.“非”.“或”.“异或”.从表面上看似乎有点像逻辑运算符,但逻辑运算符是针对两个关系运算符来进行逻辑运算,而位运算符主要针对两个二进制数的位进行逻辑运算.以下 ...
- sql: sql developer tunnel转接
Use putty tunnel instead of login terminal server 有时候本地直接ping不通sql 的server, 但另一个server能连上,这时就可以把端口和i ...
- hdoj 1286 找新朋友 【数论之欧拉函数】
找新朋友 Time Limit: 2000/1000 MS (Java/Others) Memory Limit: 65536/32768 K (Java/Others) Total Submi ...
- memset,memcpy,memmove,strcpy,strcat,strcmp的实现(其实很简单,每个程序都只有几行代码)
面试中的几个小问题 1.对stl中list封装(参考1): 2.对重要C函数实现(参考2): //memset void *memset(void *buffer, int c, int count) ...
- Windows Azure 安全最佳实践 - 第 1 部分:深度解析挑战防御对策
我每次与开发人员讨论将应用程序迁移到云时都围绕着两个主要问题. 1. 首先是业务.将应用程序迁移到云可以带来怎样的规模经济? 2. 其次是安全问题."云的安全性如何,尤其是Windows A ...
- hdu4726贪心
Kia's Calculation Time Limit: 2000/1000 MS (Java/Others) Memory Limit: 32768/32768 K (Java/Others ...