C++之类外定义成员函数、inline 成员函数详解
在使⽤类函数时,要注意调⽤它的权限(它能否被调⽤)以及它的作⽤域(函数能使⽤什么范围中的数据和函数)。例如私有的成员函数只能被本类中的其它成员函数所调⽤,⽽不能被类外调⽤。成员函数可以访问本类中任何成员(包括私有的和公⽤的),可以引⽤在本作⽤域中有效的数据。
⼀般的做法是将需要被外界调⽤的成员函数指定为public ,它们是类的对外接⼝。但应注意,并⾮要求把所有成员函数都指定为public 。有的函数并不是准备为外界调⽤的,⽽是为本类中的成员函数所调⽤的,就应该将它们指定为private 。这种函数的作⽤是⽀持其它函数的操作,是类中其它成员的⼯具函数(utility function),类外⽤户不能调⽤这些私有的⼯具函数。
类的成员函数是类体中⼗分重要的部分。如果⼀个类中不包含成员函数,就等同于C 语⾔中的结构体了,体现不出类在⾯向对象程序设计中的作⽤。
在类外定义成员函数
在前⾯已经看到成员函数是在类体中定义的。也可以在类体中只写成员函数的声明,⽽在类的外⾯进⾏函数定义。如:
注意:在类体中直接定义函数时,不需要在函数名前⾯加上类名,因为函数属于哪⼀个类是不⾔⽽喻的。
贾栩
但成员函数在类外定义时,必须在函数名前⾯加上类名,予以限定(qualifed)," :: "是作⽤域限定符(field qualifier)或称作⽤域运算符,⽤它声明函数是属于哪个类的。如果在作⽤域运算符“::”的前⾯没有类名,或者函数名前⾯既⽆类名⼜⽆作⽤域运算符“::”,如
::display( ) 或 display( )
则表⽰display 函数不属于任何类,这个函数不是成员函数,⽽是全局函数,即⾮成员函数的⼀般普通函数。
类函数必须先在类体中作原型声明,然后在类外定义,也就是说类体的位置应在函数定义之前,否则编译时会出错。
虽然函数在类的外部定义,但在调⽤成员函数时会根据在类中声明的函数原型找到函数的定义(函数代码),从⽽执⾏该函数。
在类的内部对成员函数作声明,⽽在类体外定义成员函数,这是程序设计的⼀种良好习惯。如果⼀个函数,其函数体只有2-3⾏,⼀般可在声明类时在类体中定义。多于3⾏的函数,⼀般在类体内声明,在类外定义。
inline 成员函数
关于内置(inline )函数,在前边已经作过介绍,请猛击:。类的成员函数也可以指定为内置函数。
在类体中定义的成员函数的规模⼀般都很⼩,⽽系统调⽤函数的过程所花费的时间开销相对是⽐较⼤的。调⽤⼀个函数的时间开销远远⼤于⼩规模函数体中全部语句的执⾏时间。为了减少时间开销,如果在类体中定义的成员函数中不包括循环等控制结构,C++系统会⾃动将它们作为内置(inline)函数来处理。
也就是说,在程序调⽤这些成员函数时,并不是真正地执⾏函数的调⽤过程(如保留返回地址等处理),⽽是把函数代码嵌⼊程序的调⽤点。这样可以⼤⼤减少调⽤成员函数的时间开销。C++要求对⼀般的内置函数要⽤关键字inline 声明,但对类内定义的成员函数,可以省略inline ,因为这些成员函数已被隐含地指定为内置函数。如:其中第3⾏
void display( )
也可以写成
inline void display( )
将display 函数显式地声明为内置函数。
以上两种写法是等效的。对在类体内定义的函数,⼀般都省写inline 。应该注意的是,如果成员函数不在类体内定义,⽽在类体外定义,系统并不把它默认为内置(inline )函数,调⽤这些成员函数的过程和调⽤⼀般函数的过程是相同的。如果想将这些成员函数指定为内置函数,应当⽤inline 作显式声明。如:1
2
3
t9550
4
5
手绘风景6
7
8
9
10
11不要再来伤害我歌词
12
13
14
15
16
17class Student {public :void display( ); //公⽤成员函数原型声明private :int num;string name;char x;//以上3⾏是私有数据成员};void Student::display( )//在类外定义display 类函数{cout<<"num:"<<num<<endl;cout<<"name:"<<name<<endl;cout<<"x:"<<x<<endl;}Student stud1,stud2; //定义两个类对象
1
戴笠胡蝶
2
芥末的英语3
4
5
6
7
8
9
10
11
清扫垃圾
12
13class Student {public :void display( ){cout<<"num:"<<num<<endl;cout<<"name:"<<name<<endl;cout<<"x:"<<x<<endl;}private :int num;string name;char x;};
在前⾯曾提到过,在函数的声明或函数的定义两者之⼀作inline 声明即可。值得注意的是,如果在类体外定义inline 函数,则必须将类定义和成员函数的定义都放在同⼀个头⽂件中(或者写在同⼀个源⽂件中),否则编译时⽆法进⾏置换(将函数代码的拷贝嵌⼊到函数调⽤点)。但是这样做,不利于类的接⼝与类的实现分离,不利于信息隐蔽。虽然程序的执⾏效率提⾼了,但从软件⼯程质量的⾓度来看,这样做并不是好的办法。只有在类外定义的成员函数规模很⼩⽽调⽤频率较⾼时,才将此成员函数指定为内置函数。
注意:
1、成员函数需要把实现放在头⽂件中才会是默认内联函数,如果没有放在头⽂件中则不会默认是内联;
自律与他律
2、内联与否,只是你的建议,是否真正内联,得看编译器的意思,写了inline ,或者你把类⽅法实现写在头⽂件,意味着你希望编译器帮你内联,但是是否真正内联,要看编译器,如果你的内联函数写得很复杂,编译器不⼀定会帮你内联;
3、 ⼀般需要重复使⽤的短⼩函数⽤内联。1
2
3
4
5
6
7
8
9
10
11
12class Student {public : inline void display( );//声明此成员函数为内置函数private :int num;string
name;char x;};inline void Student::display( ) // 在类外定义display 函数为内置函数{cout<<"num:"<<num<<endl;cout<<"name:"<<name<<endl;cout<<"x:"<<x<<endl;}