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