当前位置导航:炫浪网>>网络学院>>编程开发>>C++教程>>C++进阶与实例

基础入门:C++的效率浅析

    自从七十年代C语言诞生以来,一直以其灵活性、高效率和可移植性为软件开发人员所钟爱,成为系统软件开发的首选工具。而C++作为C语言的继承和发展,不仅保留了C语言的高度灵活、高效率和易于理解等诸多优点,还包含了几乎所有面向对象的特征,成为新一代软件系统构建的利器。

    相对来说,C语言是一种简洁的语言,所涉及的概念和元素比较少,主要是:宏(macro)、指针(pointer)、结构(struct)、函数(function)和数组(array),比较容易掌握和理解。而C++不仅包含了上面所提到的元素,还提供了私有成员(private members)、公有成员(public members)、函数重载(function overloading)、缺省参数(default parameters)、构造函数、析构函数、对象的引用(references)、操作符重载(operator overloading)、友元(friends)、模板(templates)、异常处理(exceptions)等诸多的要素,给程序员提供了更大的设计空间,同时也增加了软件设计的难度。

    C语言之所以能被广泛的应用,其高效率是一个不可忽略的原因,C语言的效率能达到汇编语言的80%以上,对于一种高级语言来说,C语言的高效率就不言而喻了。那么,C++相对于C来说,其效率如何呢?实际上,C++的设计者stroustrup要求C++效率必须至少维持在与C相差5%以内,所以,经过精心设计和实现的C++同样有很高的效率,但并非所有C++程序具有当然的高效率,由于C++的特殊性,一些不好的设计和实现习惯依然会对系统的效率造成较大的影响。同时,也由于有一部分程序员对C++的一些底层实现机制不够了解,就不能从原理上理解如何提高软件系统的效率。

    本文主要讨论两个方面的问题:第一,对比C++的函数调用和C函数调用,解析C++的函数调用机制;第二,例举一些C++程序员不太注意的技术细节,解释如何提高C++的效率。为方便起见,本文的讨论以下面所描述的单一继承为例(多重继承有其特殊性,另作讨论)。

 class X
{
public:
virtual ~X(); //析构函数
virtual void VirtualFunc(); //虚函数
inline int InlineFunc() { return m_iMember}; //内联函数
void NormalFunc(); //普通成员函数
static void StaticFunc(); //静态函数
private:
int m_iMember;

};

class XX: public X
{
public:
XX();
virtual ~XX();
virtual void VirtualFunc();
private:
String  m_strName;
int   m_iMember2;

};

    C++的的函数分为四种:内联函数(inline member function)、静态成员函数(static member function)、虚函数(virtual member function)和普通成员函数。

    内联函数类似于C语言中的宏定义函数调用,C++编译器将内联函数的函数体扩展在函数调用的位置,使内联函数看起来象函数,却不需要承受函数调用的开销,对于一些函数体比较简单的内联函数来说,可以大大提高内联函数的调用效率。但内联函数并非没有代价,如果内联函数体比较大,内联函数的扩展将大大增加目标文件和可运行文件的大小;另外,inline关键字对编译器只是一种提示,并非一个强制指令,也就是说,编译器可能会忽略某些inline关键字,如果被忽略,内联函数将被当作普通的函数调用,编译器一般会忽略一些复杂的内联函数,如函数体中有复杂语句,包括循环语句、递归调用等。所以,内联函数的函数体定义要简单,否则在效率上会得不偿失。

    静态函数的调用,如下面的几种方式:

 X obj; X* ptr = &obj;
obj.StaticFunc();
ptr->StaticFunc();
X::StaticFunc();
    将被编译器转化为一般的C函数调用形式,如同这样:
 mangled_name_of_X_StaticFunc();
  //obj.StaticFunc();
mangled_name_of_X_StaticFunc();
 // ptr->StaticFunc();
mangled_name_of_X_StaticFunc();
// X::StaticFunc();

    mangled_name_of_X_StaticFunc()是指编译器将X::StaticFunc()函数经过变形(mangled)后的内部名称(C++编译器保证每个函数将被mangled为独一无二的名称,不同的编译器有不同的算法,C++标准并没有规定统一的算法,所以mangled之后的名称也可能不同)。可以看出,静态函数的调用同普通的C函数调用有完全相同的效率,并没有额外的开销。

    普通成员函数的调用,如下列方式:

 X obj; X* ptr = &obj;
obj.NormalFunc();
ptr->NormalFunc();
    将被被编译器转化为如下的C函数调用形式,如同这样。
 mangled_name_of_X_NormalFunc(&obj);
 //obj.NormalFunc();
mangled_name_of_X_NormalFunc(ptr);
 // ptr->NormalFunc();

    可以看出普通成员函数的调用同普通的C调用没有大的区别,效率与静态函数也相同。编译器将重新改写函数的定义,增加一个const X* this参数将调用对象的地址传送进函数。

共2页 首页 上一页 1 2 下一页 尾页 跳转到
相关内容
赞助商链接