优雅的使用inline(GeekBand第二周)

第一周的课程中,老师提到,使用inline定义函数会提高效率,当时只是简单的记下了。这周作业中,下意识的,在Rectangle.h文件中声明一个类:

然后在对应的cpp文件中添加实现,按照老师的建议,在所有不复杂的定义之前,都添加了一个inline关键字:

编译没有问题,perfect!

接下来写测试代码,调用Rectangle的构造,然后问题就来了:

错误提示很明显,函数未定义。可是,之前有定义,而且在调用之前的编译都没有问题,什么鬼?!

接下来逐步调整代码(都是简单的步骤,具体过程就不啰嗦了),发现了规律:

方式一:

1. rectangle.h中声明成员函数,不加inline;

2. rectangle.cpp中实现,加inline;

3. main()中调用,报错,不调用,没有问题。(这里的main()不在rectangle.cpp中,下同);

方式二:

1. rectangle.h中声明成员函数,加inline;

2. rectangle.cpp中实现,不加inline;

3. main()中调用,报错,不调用,没有问题。

方式三:

1. rectangle.h中声明成员函数,不加inline;

2. rectangle.cpp中实现,不加inline;

3. main()中调用,没有问题。

方式四:

1. rectangle.h中声明成员函数,不加inline;

2. rectangle.h中实现,加inline;

3. main()中调用,没有问题。

反复验证后得出结论,inline function的定义,需要写在相应的头文件中。回过头去翻看了课程视频,老师似乎也没有提到这一点。

为了确认这个问题,找了c++11标准,找到里边关于inline function的说明:

An inline function shall be defined in every translation unit in which it is odr-used.

内联函数需要在每个用到它的编译单元定义。

A function declaration (8.3.5, 9.3, 11.3) with an inline specifier declares an inline function. The inline specifier indicates to the implementation that inline substitution of the function body at the point of call is to be preferred to the usual function call mechanism(每个调用到内联函数的地方,都会替换成内联函数的函数体). An implementation is not required to perform this inline substitution at the point of call; however, even if this inline substitution is omitted, the other rules for inline functions defined by 7.1.2 shall still be respected.

A function defined within a class definition is an inline function. The inline specifier shall not appear on a block scope function declaration.91 If the inline specifier is used in a friend declaration, that declaration shall be a definition or the function shall have previously been declared inline.

An inline function shall be defined in every translation unit in which it is odr-used and shall have exactly the same definition in every case (3.2).(内联函数必须在每个用到的编译单元定义,且每个定义需要相同) [Note: A call to the inline function may be encountered before its definition appears in the translation unit. —end note] If the definition of a function appears in a translation unit before its first declaration as inline, the program is ill-formed. If a function with external linkage is declared inline in one translation unit, it shall be declared inline in all translation units in which it appears; no diagnostic is required. An inline function with external linkage shall have the same address in all translation units. A static local variable in an extern inline function always refers to the same object. A string literal in the body of an extern inline function is the same object in different translation units. [Note: A string literal appearing in a default argument is not in the body of an inline function merely because the expression is used in a function call from that inline function. —end note] A type defined within the body of an extern inline function is the same type in every translation unit.



与此相关的描述,已经在引文中添加了翻译,就是一条:需要在每个用到的编译单元做出定义,且每个定义需要保持一致。

看到这里,又做了一次尝试:


方式五:

1. rectangle.h中声明成员函数,不加inline;

2. rectangle.cpp中实现,加inline;

2. test.cpp中添加同样的实现,加inline;

3. main()中调用,没有问题。

这种方法虽然可行,但是存在一个弊端,工程项目不断添加新的文件,很难保证inline在每个.c文件中都能定义相同,所以并不可取。

综上所述,我们使用inline的时候,还是应该在头文件的声明中,直接写出函数的定义,non-inline函数的定义,则写到对应的cpp文件中,提高程序可读性和可维护性。


PS. 今天周末,难得有空,回顾了一下这篇笔记,又针对incline function的研究查了些资料,果然发现更多精彩。在这个这个链接  中,发现了前辈对这一问题的讨论。

"But putting function bodies at the end of my header is ugly.  Isn't there a way to avoid that?"

Yep!  Just move the function bodies to another header:

果然,代码更清晰,避免了circular reference的同时,也让代码更加优雅。值得学习。

最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 204,921评论 6 478
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 87,635评论 2 381
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 151,393评论 0 338
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 54,836评论 1 277
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 63,833评论 5 368
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 48,685评论 1 281
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 38,043评论 3 399
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 36,694评论 0 258
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 42,671评论 1 300
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 35,670评论 2 321
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 37,779评论 1 332
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 33,424评论 4 321
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 39,027评论 3 307
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 29,984评论 0 19
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 31,214评论 1 260
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 45,108评论 2 351
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 42,517评论 2 343

推荐阅读更多精彩内容