类和对象( 二 )

注意:在类体中直接定义函式时,不需要在函式名前面加上类名,因为函式属于哪一个类是不言而喻的 。但成员函式在类外定义时,必须在函式名前面加上类名,予以限定(qualifed),“∷”是作用域限定符(field qualifier)或称作用域运算符,用它声明函式是属于哪个类的 。如果在作用域运算符“∷”的前面没有类名,或者函式名前面既无类名又无作用域运算符“∷”,如 ∷display( ) 或 display( ),则表示display函式不属于任何类,这个函式不是成员函式,而是全局函式,即非成员函式的一般普通函式 。类函式必须先在类体中作原型声明,然后在类外定义,也就是说类体的位置应在函式定义之前,否则编译时会出错 。虽然函式在类的外部定义,但在调用成员函式时会根据在类中声明的函式原型找到函式的定义(函式代码),从而执行该函式 。在类的内部对成员函式作声明,而在类体外定义成员函式,这是程式设计的一种良好习惯 。如果一个函式,其函式体只有2-3行,一般可在声明类时在类体中定义 。多于3行的函式,一般在类体内声明,在类外定义 。inline 函式在类体中定义的成员函式的规模一般都很小,而系统调用函式的过程所花费的时间开销相对是比较大的 。调用一个函式的时间开销远远大于小规模函式体中全部语句的执行时间 。为了减少时间开销,如果在类体中定义的成员函式中不包括循环等控制结构,C++系统会自动将它们作为内置(inline )函式来处理 。也就是说,在程式调用这些成员函式时,并不是真正地执行函式的调用过程(如保留返回地址等处理),而是把函式代码嵌入程式的调用点 。这样可以大大减少调用成员函式的时间开销 。C++要求对一般的内置函式要用关键字inline声明,但对类内定义的成员函式,可以省略inline,因为这些成员函式已被隐含地指定为内置函式 。如classStudent{public:voiddisplay(){cout<<″num:″<<num<<endl;cout<<″name:″<<name<<endl;cout<<″sex:″<<sex<<endl;}private:intnum;stringname;charsex;};其中第3行void display( ) 也可以写成inline void display( )将display函式显式地声明为内置函式 。以上两种写法是等效的 。对在类体内定义的函式,一般都省写inline 。应该注意的是: 如果成员函式不在类体内定义,而在类体外定义,系统并不把它默认为内置(inline )函式,调用这些成员函式的过程和调用一般函式的过程是相同的 。如果想将这些成员函式指定为内置函式,应当用inline作显式声明 。如classStudent{public:inlinevoiddisplay();//声明此成员函式为内置函式private:intnum;stringname;charsex;};inlinevoidStudent∷display()//在类外定义display函式为内置函式{cout<<″num:″<<num<<endl;cout<<″name:″<<name<<endl;cout<<″sex:″<<sex<<endl;} 在函式的声明或函式的定义两者之一作inline声明即可 。值得注意的是: 如果在类体外定义inline函式,则必须将类定义和成员函式的定义都放在同一个头档案中(或者写在同一个源档案中),否则编译时无法进行置换(将函式代码的拷贝嵌入到函式调用点) 。但是这样做,不利于类的接口与类的实现分离,不利于信息隐蔽 。虽然程式的执行效率提高了,但从软体工程质量的角度来看,这样做并不是好的办法 。只有在类外定义的成员函式规模很小而调用频率较高时,才将此成员函式指定为内置函式 。成员函式存储用类去定义对象时,系统会为每一个对象分配存储空间 。如果一个类包括了数据和函式,要分别为数据和函式的代码分配存储空间 。按理说,如果用同一个类定义了10个对象,那幺就需要分别为10个对象的数据和函式代码分配存储单元 。能否只用一段空间来存放这个共同的函式代码段,在调用各对象的函式时,都去调用这个公用的函式代码 。显然,这样做会大大节约存储空间 。C++编译系统正是这样做的,因此每个对象所占用的存储空间只是该对象的数据部分所占用的存储空间,而不包括函式代码所占用的存储空间 。如果声明了一个类: