C++成員函數(shù)—C++成員函數(shù)的定義和重載
2020-05-23 14:26:07
供稿:網(wǎng)友
我們已經(jīng)學(xué)會(huì)如何調(diào)用成員函數(shù),那么成員函數(shù)又是如何聲明和定義的呢?它和普通函數(shù)有著什么異同點(diǎn)呢?
普通函數(shù)在使用之前必須聲明和定義,成員函數(shù)也是這樣。不過(guò)成員函數(shù)是屬于某一個(gè)類(lèi)的,所以只能在類(lèi)的內(nèi)部聲明,即在定義類(lèi)的時(shí)候?qū)懨鞒蓡T函數(shù)的函數(shù)原型,同時(shí)要注意此函數(shù)是公有的還是私有的。如果一個(gè)類(lèi)的某個(gè)成員函數(shù)是私有的,那么它只能被這個(gè)類(lèi)的其他成員函數(shù)調(diào)用。成員函數(shù)的函數(shù)原型和普通函數(shù)的函數(shù)原型在寫(xiě)法上是一樣的。比如:
class Node//定義一個(gè)鏈表結(jié)點(diǎn)類(lèi)
{
public:
int readi();//通過(guò)該函數(shù)讀取idata
char readc();//通過(guò)該函數(shù)讀取cdata
bool seti(int i);//通過(guò)該函數(shù)修改idata
bool setc(char c);//通過(guò)該函數(shù)修改cdata
bool setp(Node *p);//通過(guò)該函數(shù)設(shè)置前驅(qū)結(jié)點(diǎn)
bool setn(Node *n);//通過(guò)該函數(shù)設(shè)置后繼結(jié)點(diǎn)
private:
int idata;//存儲(chǔ)數(shù)據(jù)保密
char cdata; //存儲(chǔ)數(shù)據(jù)保密
Node *prior;//前驅(qū)結(jié)點(diǎn)的存儲(chǔ)位置保密
Node *next;//后繼結(jié)點(diǎn)的存儲(chǔ)位置保密
};
常成員函數(shù)
由于數(shù)據(jù)封裝在類(lèi)的內(nèi)部,在處理一些問(wèn)題的時(shí)候就需要小心翼翼,不能把成員數(shù)據(jù)破壞了。以前我們介紹使用const來(lái)保護(hù)變量(就變成了常量),或保護(hù)指針?biāo)赶虻膬?nèi)容,那么在類(lèi)中,我們也可以使用const這個(gè)保留字來(lái)保護(hù)成員數(shù)據(jù)不被成員函數(shù)改變。我們把這種成員函數(shù)稱(chēng)為常成員函數(shù)。它的寫(xiě)法就是在函數(shù)的參數(shù)表后面加上一個(gè)const,比如:
int readi() const;//通過(guò)該函數(shù)讀取idata,但不能改變?nèi)魏纬蓡T數(shù)據(jù)
char readc() const;//通過(guò)該函數(shù)讀取cdata,但不能改變?nèi)魏纬蓡T數(shù)據(jù)
使用常成員函數(shù),就保證了成員數(shù)據(jù)的安全,在此函數(shù)中任何修改成員數(shù)據(jù)的語(yǔ)句將被編譯器拒之門(mén)外。
成員函數(shù)的重載
和普通函數(shù)類(lèi)似,在一個(gè)類(lèi)中也可以有成員函數(shù)重載。成員函數(shù)的重載在規(guī)則上和普通函數(shù)也并無(wú)差別,這里不再贅述。
最終,我們將鏈表結(jié)點(diǎn)類(lèi)的定義修改如下:
class Node//定義一個(gè)鏈表結(jié)點(diǎn)類(lèi)
{
public:
int readi() const;//通過(guò)該函數(shù)讀取idata,但不能改變?nèi)魏纬蓡T數(shù)據(jù)
char readc() const;//通過(guò)該函數(shù)讀取cdata,但不能改變?nèi)魏纬蓡T數(shù)據(jù)
bool set(int i);//重載,通過(guò)該函數(shù)修改idata
bool set(char c);// 重載,通過(guò)該函數(shù)修改cdata
bool setp(Node *p);//通過(guò)該函數(shù)設(shè)置前驅(qū)結(jié)點(diǎn)
bool setn(Node *n);//通過(guò)該函數(shù)設(shè)置后繼結(jié)點(diǎn)
private:
int idata;//存儲(chǔ)數(shù)據(jù)保密
char cdata; //存儲(chǔ)數(shù)據(jù)保密
Node *prior;//前驅(qū)結(jié)點(diǎn)的存儲(chǔ)位置保密
Node *next;//后繼結(jié)點(diǎn)的存儲(chǔ)位置保密
};
成員函數(shù)的定義
成員函數(shù)與普通函數(shù)的不同之處,在于成員函數(shù)是屬于某一個(gè)類(lèi)的,而不能被隨意地調(diào)用。那么,我們?cè)诙x一個(gè)成員函數(shù)的時(shí)候如何來(lái)表達(dá)它是屬于某一個(gè)類(lèi)的呢?這個(gè)時(shí)候我們就要用到::操作符,它表示該函數(shù)是屬于某一個(gè)類(lèi)的,稱(chēng)為域解析操作符。因此在類(lèi)定義結(jié)束后,定義一個(gè)成員函數(shù)的格式如下:
返回值類(lèi)型類(lèi)名::函數(shù)名(參數(shù)表)
{
語(yǔ)句;
……
}
事實(shí)上,成員函數(shù)也是可以在類(lèi)的定義中定義的(此時(shí)不需要域解析操作符),但是從程序的運(yùn)行效率、可讀性、美觀性考慮,我們建議將成員函數(shù)的定義完全放在類(lèi)定義的外面。于是,鏈表結(jié)點(diǎn)類(lèi)和其成員函數(shù)的定義如下:
//node.h
class Node//定義一個(gè)鏈表結(jié)點(diǎn)類(lèi)
{
public:
int readi() const;//通過(guò)該函數(shù)讀取idata,但不能改變?nèi)魏纬蓡T數(shù)據(jù)
char readc() const;//通過(guò)該函數(shù)讀取cdata,但不能改變?nèi)魏纬蓡T數(shù)據(jù)
bool set(int i);//重載,通過(guò)該函數(shù)修改idata
bool set(char c);//重載,通過(guò)該函數(shù)修改cdata
bool setp(Node *p);//通過(guò)該函數(shù)設(shè)置前驅(qū)結(jié)點(diǎn)
bool setn(Node *n);//通過(guò)該函數(shù)設(shè)置后繼結(jié)點(diǎn)
private:
int idata;//存儲(chǔ)數(shù)據(jù)保密
char cdata;//存儲(chǔ)數(shù)據(jù)保密
Node *prior;//前驅(qū)結(jié)點(diǎn)的存儲(chǔ)位置保密
Node *next;//后繼結(jié)點(diǎn)的存儲(chǔ)位置保密
};//類(lèi)定義結(jié)束,分號(hào)切勿忘記
int Node::readi() const//成員函數(shù)readi的定義
{
return idata;
}
char Node::readc() const
{
return cdata;
}
bool Node::set(int i)//重載成員函數(shù)定義
{
idata=i;
return true;
}
bool Node::set(char c)
{
cdata=c;
return true;
}
bool Node::setp(Node *p)
{
prior=p;
return true;
}
bool Node::setn(Node *n)
{
next=n;
return true;
}
在上面這些成員函數(shù)定義中,我們可以看出成員數(shù)據(jù)(或成員函數(shù))在成員函數(shù)中可以直接使用。平時(shí)我們使用一個(gè)對(duì)象的公有成員數(shù)據(jù)時(shí),我們要寫(xiě)作“對(duì)象名.成員數(shù)據(jù)”,但是在成員函數(shù)中不需要也不能那樣寫(xiě)。接下來(lái),我們就能?chē)L試一下使用我們編寫(xiě)的類(lèi)了:(程序14.3)
//main.cpp
#include <iostream>
#include "node.h"//包含我們編寫(xiě)好的鏈表結(jié)點(diǎn)類(lèi)頭文件,必須用雙引號(hào)
using namespace std;
int main()
{
Node a;//創(chuàng)建一個(gè)鏈表結(jié)點(diǎn)對(duì)象a
a.set(1);//設(shè)置idata
a.set('A');//設(shè)置cdata
cout <<a.readi() <<endl;
cout <<a.readc() <<endl;
return 0;
}
運(yùn)行結(jié)果:
1
A
注意這個(gè)程序有兩個(gè)文件,一個(gè)是頭文件node.h,一個(gè)是源文件main.cpp。如果你忘記了如何創(chuàng)建一個(gè)頭文件,那么請(qǐng)看本書(shū)的11.2節(jié)。