豆豆首页 > 技术教程 > 程序设计 > C/C++

C++如何处理内联虚函数

http://tech.ddvip.com 2007年03月17日 05:30:20    赵湘宁
 
 

  你还可以编写更复杂的代码,其中,pfoo 所指的对象类型总是透明的,但是大多数编译器不会做任何更多的分析。即使在前面的例子中,某些编译器将会安全运行,实例化并通过一个虚表来调用。实际上,编译器总是忽略内联需要并总是使用虚表。唯一绝对的规则是代码必须工作;也就是说,虚函数必须有多态行为。

  通常,无论是显式还是隐式内联,它只是一个提示而已,并非是必须的,就象寄存器一样。编译器完全能拒绝展开一个非虚内联函数,C++编译器常常首先会报错:“内联中断-函数太大”。如果内联函数调用自身,或者你在某处传递其地址,编译器必须产生一个正常(外联?)函数。内联函数在DEBUG BUILDS中不被展开,可设置编译选项来预防。

  要想知道编译器正在做什么,唯一的方法是看它产生的代码。对于微软的编译器来说,你可以用-FA编译选项产生汇编清单。你不必知道汇编程序如何做。我鼓励你完成这个实验;这对于了解机器实际所做的事情机器有益,同时你可学习许多汇编列表中的内容。

  有关内联函数的东西比你第一次接触它时要复杂得多。有许多种情况强迫编译器产生正常函数:递归,获取函数地址,太大的那些函数和虚函数。但是如果编译器决定实例化你的内联函数,就要考虑把函数放在什么地方?它进入哪个模块?

  通常类在头文件中声明,所以如果某个cpp包含foo.h,并且编译器决定实例化CFoo::GetVal,则在cpp文件中将它实例化成一个静态函数。如果十个模块包含foo.h,编译器产生的虚函数拷贝就有十个。实际上,可以用虚表指向不同类型的GetVal拷贝,从而是相同类型的对象只产生拷贝。一些链接器能巧妙地在链接时排除冗余,但一般你是不能指望他来保证的。

  我们得出的结论是:最好不要使用内联虚函数,因为它们几乎不会被展开,即便你的函数只有一行,你最好还是将它与其它的类函数一起放在模块(cpp文件)中。当然,开发者常常将简短的虚函数放在类声明中-不是因为他们希望这个函数被展开为内联,而是因为这样做更方便和可读性更强。

[责任编辑:editorforddvip]

点击搜索更多"虚函数"相关信息
正在加载评论...
请您留言
网友昵称: 匿名发表(无需注册)
 
请输入验证码:  
如果您还不是豆豆会员,欢迎注册
 
请您注意
· 遵守国家有关法律、法规,尊重网上道德,承担一切因您的行为而直接或间接引起的法律责任。
· 豆豆网拥有管理笔名和留言的一切权利。
 
 
专题文章推荐