https://www.cnblogs.com/wuchanming/p/4061654.html
類的成員函數(簡稱類函數)是函數的一種,它的用法和作用和前面介紹過的函數基本上是一樣的,它也有返回值和函數類型,它與一般函數的區別只是:它是屬於一個類的成員,出現在類體中。它可以被指定為private(私有的)、public (公用的)或protected(受保護的)。
在使用類函數時,要注意調用它的權限(它能否被調用)以及它的作用域(函數能使用什么范圍中的數據和函數)。例如私有的成員函數只能被本類中的其它成員函數所調用,而不能被類外調用。成員函數可以訪問本類中任何成員(包括私有的和公用的),可以引用在本作用域中有效的數據。
一般的做法是將需要被外界調用的成員函數指定為public,它們是類的對外接口。但應注意,並非要求把所有成員函數都指定為public。有的函數並不是准備為外界調用的,而是為本類中的成員函數所調用的,就應該將它們指定為private。這種函數的作用是支持其它函數的操作,是類中其它成員的工具函數(utility function),類外用戶不能調用這些私有的工具函數。
類的成員函數是類體中十分重要的部分。如果一個類中不包含成員函數,就等同於C語言中的結構體了,體現不出類在面向對象程序設計中的作用。
在類外定義成員函數
在前面已經看到成員函數是在類體中定義的。也可以在類體中只寫成員函數的聲明,而在類的外面進行函數定義。如:
class Student { public : void display( ); //公用成員函數原型聲明 private : int num; string name; char sex; //以上3行是私有數據成員 }; void Student::display( )//在類外定義display類函數 { cout<<"num:"<<num<<endl; cout<<"name:"<<name<<endl; cout<<"sex:"<<sex<<endl; } Student stud1,stud2; //定義兩個類對象
但成員函數在類外定義時,必須在函數名前面加上類名,予以限定(qualifed)," :: "是作用域限定符(field qualifier)或稱作用域運算符,用它聲明函數是屬於哪個類的。
如果在作用域運算符“::”的前面沒有類名,或者函數名前面既無類名又無作用域運算符“::”,如
::display( ) 或 display( )
則表示display函數不屬於任何類,這個函數不是成員函數,而是全局函數,即非成員函數的一般普通函數。
類函數必須先在類體中作原型聲明,然后在類外定義,也就是說類體的位置應在函數定義之前,否則編譯時會出錯。
雖然函數在類的外部定義,但在調用成員函數時會根據在類中聲明的函數原型找到函數的定義(函數代碼),從而執行該函數。
在類的內部對成員函數作聲明,而在類體外定義成員函數,這是程序設計的一種良好習慣。如果一個函數,其函數體只有2-3行,一般可在聲明類時在類體中定義。多於3行的函數,一般在類體內聲明,在類外定義。
inline 成員函數
關於內置(inline )函數,在前邊已經作過介紹,請猛擊:C++內置函數。類的成員函數也可以指定為內置函數。
在類體中定義的成員函數的規模一般都很小,而系統調用函數的過程所花費的時間開銷相對是比較大的。調用一個函數的時間開銷遠遠大於小規模函數體中全部語句的執行時間。為了減少時間開銷,如果在類體中定義的成員函數中不包括循環等控制結構,C++系統會自動將它們作為內置(inline)函數來處理。(類內定義的函數完全等同於內置函數吧?)
也就是說,在程序調用這些成員函數時,並不是真正地執行函數的調用過程(如保留返回地址等處理),而是把函數代碼嵌入程序的調用點。這樣可以大大減少調用成員函數的時間開銷。C++要求對一般的內置函數要用關鍵字inline聲明,但對類內定義的成員函數,可以省略inline,因為這些成員函數已被隱含地指定為內置函數。如:
class Student { public : void display( ) { cout<<"num:"<<num<<endl;cout<<"name:" <<name<<endl;cout<<"sex:"<<sex<<endl; } private : int num; string name; char sex; };
void display( )
也可以寫成
inline void display( )
將display函數顯式地聲明為內置函數。
以上兩種寫法是等效的。對在類體內定義的函數,一般都省寫inline。
應該注意的是,如果成員函數不在類體內定義,而在類體外定義,系統並不把它默認為內置(inline )函數,調用這些成員函數的過程和調用一般函數的過程是相同的。如果想將這些成員函數指定為內置函數,應當用inline作顯式聲明。如:
class Student { public : inline void display( );//聲明此成員函數為內置函數 private : int num; string name; char sex; }; inline void Student::display( ) // 在類外定義display函數為內置函數 { cout<<"num:"<<num<<endl;cout<<"name:"<<name<<endl;cout<<"sex:"<<sex<<endl; }
在前面曾提到過,在函數的聲明或函數的定義兩者之一作inline聲明即可。值得注意的是,如果在類體外定義inline函數,則必須將類定義和成員函數的定義都放在同一個頭文件中(或者寫在同一個源文件中),否則編譯時無法進行置換(將函數代碼的拷貝嵌入到函數調用點)。但是這樣做,不利於類的接口與類的實現分離,不利於信息隱蔽。雖然程序的執行效率提高了,但從軟件工程質量的角度來看,這樣做並不是好的辦法。只有在類外定義的成員函數規模很小而調用頻率較高時,才將此成員函數指定為內置函數。