在C++程序中,创建/销毁对象是影响性能的一个非常突出的操作。首先,如果是从全局堆中生成对象,则需要首先进行动态内存分配操作。众所周知,动态分配/回收在C/C++程序中一直都是非常耗时的。因为牵涉到寻找匹配大小的内存块,找到后可能还需要截断处理,然后还需要修改维护全局堆内存使用情况信息的链表等。因为意识到频繁的内存操作会严重影响性能,所以已经发展出很多技术用来缓解和降低这种影响,例如内存池技术。
尽量少使用值传递,而使用常量引用传递。
虚函数带来的开销:
① 空间:每个支持虚拟函数的类,都有一个虚拟函数表,这个虚拟函数表的大小跟该类拥有的虚拟函数的多少成正比,虚拟函数表属于类所有,无论有多少个对象,都只有一个虚拟函数表。
② 空间:通过支持虚拟函数的类生成的每一个对象都有一个指向该类虚拟函数表的指针。有多少个对象,就有多少个虚拟函数表指针。
③ 时间:支持虚拟函数的类的每一个对象,在构造时,都会初始化虚拟函数表指针,使其指向虚拟函数表。
④ 时间:当通过指针或引用调用虚拟函数时,跟普通函数调用相比,会多一个根据虚拟函数指针找到虚拟函数表的操作。
⑤ 可能无法使用内联函数。因为内联函数是在“编译期”,编译期将调用内联函数的地方用内联函数体的代码代替(内联展开),但是虚拟函数本质上是“运行期”行为。在“编译期”,编译器无法确定要动态绑定的虚函数会绑定到那个函数上,所以无法内联展开。不过,如果在编译时能够确定调用哪个虚函数,那还是可以内联的,只是,这样它就失去了作为虚拟函数的功能。
据书上分析,采用虚拟函数跟不采用虚函数相比带来的负面影响是:虚函数表的空间开销和无法使用内联函数。虚函数表占的空间较小,可以忽略,所以主要缺点是无法使用内联函数。但是不采用虚函数就使得代码可扩展性和可维护性大大降低,而面向对象编程的一个重要目的就是增加程序的可扩展性和可维护性,即当程序的业务逻辑发生改变时,对原程序的修改非常方便。
因此在性能和其他方面特性的选择方面,需要开发人员根据实际情况进行权衡和取舍。当然在权衡之前,需要通过性能检测确认性能的瓶颈是由于虚拟函数没有利用到内联函数的优势这一缺陷引起;否则可以不必考虑虚拟函数的影响。
转载:http://www.cnblogs.com/cswuyg/archive/2010/08/22/1805840.html