根據面向對象守則,數據應該儘可能被封裝,類中成員函數和friend函數的封裝性要比非成員函數的封裝性低。爲什麼呢?這是因爲越少的代碼能夠訪問對象內的數據,那麼越多的數據能夠被封裝,我們也能夠越能自由地改變對象的數據,這樣一旦改變成員數據的話能夠將其他的改動變的最低。
非成員函數和非友元函數能夠實現較大的封裝性,這是因爲它們的存在並不增加能夠訪問class中private成員的數量。
假設有一個類CWebBrowser:
class CwebBrowser
{
public:
CwebBrowser(){}
~CwebBrowser(){}
void clearCahe();
void clearHistory();
private:
};
我們想設計一個函數來調用clearCache() 和 clearHistory()函數。可以在類中定義一個clearall() 函數,也可以如下實現:
void clearall(CwebBrowser& wb)
{
wb.clearCahe();
wb.clearHistory();
}
在類外通過對象調用兩個clear函數。這種做法能夠帶來更好的封裝性。我們將這個函數叫做類CwebBrowser的工具函數。但是這樣做不保證這個工具函數不成爲其他類的成員。所以一般做法是將類和該函數放在一個同命名空間裏。所謂命名空間是爲了將一些全局實體分隔開來,避免重複定義的情況出現。比如:
namespace ns1
{
int a;
double b;
}
ns1的成員包括a 和 b , 但是a,b仍然是全局變量,僅僅是把額外加了一個命名空間ns1這個範圍而已。
通常不同的用戶關注點不同,比如在這個關於瀏覽器的CwebBrowser類中,有的用戶關注書籤,有的用戶關注cookie。用命名空間還可以用不同的頭文件表明不同的“關注點”。
具體做法是:
在webbrowser.h文件中定義了一個命名空間,由CwebBrowser類和clearall()函數構成。
using namespace std;
namespace WebBrowserStuff{
class CwebBrowser
{
public:
CwebBrowser(){}
~CwebBrowser(){}
void clearCahe();
void clearHistory();
private:
};
void CwebBrowser::clearCahe()
{
cout << "Cache cleared!"<< endl;
}
void CwebBrowser::clearHistory()
{
cout << "History cleared!" << endl;
}
void clearall(CwebBrowser& wb)
{
wb.clearCahe();
wb.clearHistory();
}
}
在webbrowserbookmarks.h 中往命名空間中再添加函數:
using namespace std;
//往namespace裏添加一個函數addbookmarks()
namespace WebBrowserStuff
{
void addbookmarks()
{
cout << "add a book mark successfully!" << endl;
}
}
還可以在另一個webbrowserothers.h中再添加函數:
using namespace std;
namespace WebBrowserStuff
{
void addsomething()
{
cout << "add something succesfully!" << endl;
}
}
main函數:
#include <iostream>
#include "webbrowser.h"
#include "webbrowserbookmarks.h"
#include "webbrowserothers.h"
int main()
{
WebBrowserStuff::CwebBrowser web;
WebBrowserStuff::addbookmarks();
WebBrowserStuff::addsomething();
WebBrowserStuff::clearall(web);
system("pause");
return 0;
}
這樣便於用戶擴展不同的工具函數,只需要添加一個頭文件聲明就行。