青青草原综合久久大伊人导航_色综合久久天天综合_日日噜噜夜夜狠狠久久丁香五月_热久久这里只有精品

冷夜 C++ 小棧

關(guān)于C++的一些經(jīng)驗(yàn)與心得,還會(huì)有一些技術(shù)文摘

  C++博客 :: 首頁(yè) :: 聯(lián)系 :: 聚合  :: 管理
  6 Posts :: 5 Stories :: 12 Comments :: 0 Trackbacks

常用鏈接

留言簿(10)

我參與的團(tuán)隊(duì)

搜索

  •  

最新評(píng)論

閱讀排行榜

評(píng)論排行榜

一個(gè)有趣的現(xiàn)象,摘自CSDN 吹云Blog《C++從零開始(十二)——何謂面向?qū)ο缶幊趟枷搿吩?/FONT>http://blog.csdn.net/chuiyun/archive/2004/11/26/194722.aspx

    之所以摘錄這段文章,是因?yàn)槲移婀窒旅娴睦泳谷徽娴哪軌蚓幾g通過--在引用的文件中篡改類的private為public就可以直接訪問私有變量,而且能夠正常訪問和賦值。
    下面是摘錄的原文,有興趣的朋友不妨也試試編個(gè)代碼試驗(yàn)一下。

-------------------------------------------------------------------

封裝

    先來(lái)看現(xiàn)在在各類VC教程中關(guān)于對(duì)象的講解中經(jīng)常能看見的如下的一個(gè)類的設(shè)計(jì)。
    class Person
    { private: char m_Name[20]; unsigned long m_Age; bool m_Sex;
      public:  const char* GetName() const;  void SetName( const char* );
               unsigned long GetAge() const; void SetAge( unsigned long );
               bool GetSex() const;          void SetSex( bool );
    };
    上面將成員變量全部定義為private,然后又提供三對(duì)Get/Set函數(shù)來(lái)存取上面的三個(gè)成員變量(因?yàn)樗鼈兪莗rivate,外界不能直接存取),這三對(duì)函數(shù)都是public的,為什么要這樣?那些教材將此稱作封裝,是對(duì)類Person的內(nèi)部?jī)?nèi)存布局的封裝,這樣外界就不知道其在內(nèi)存上是如何布局的并進(jìn)而可以保證內(nèi)存的有效性(只由類自身操作其實(shí)例)。
    首先要確認(rèn)上面設(shè)計(jì)的荒謬性,它是正宗的“有門沒鎖”毫無(wú)意義。接著再看所謂的對(duì)內(nèi)存布局的封裝。回想在《C++從零開始(十)》中說(shuō)的為什么每個(gè)要使用類的源文件的開頭要包含相應(yīng)的頭文件。假設(shè)上面是在Person.h中的聲明,然后在b.cpp中要使用類Person,本來(lái)要#include "Person.h",現(xiàn)在替換成下面:
    class Person
    { public: char m_Name[20]; unsigned long m_Age; bool m_Sex;
      public: const char* GetName() const;  void SetName( const char* );
              unsigned long GetAge() const; void SetAge( unsigned long );
              bool GetSex() const;          void SetSex( bool );
    };
    然后在b.cpp中照常使用類Person,如下:
    Person a, b; a.m_Age = 20; b.GetSex();
    這里就直接使用了Person::m_Age了,就算不做這樣蹩腳的動(dòng)作,依舊#include "Person.h",如下:
    struct PERSON { char m_Name[20]; unsigned long m_Age; bool m_Sex; };
    Person a, b; PERSON *pP = ( PERSON* )&a; pP->m_Age = 40;
    上面依舊直接修改了Person的實(shí)例a的成員Person::m_Age,如何能隱藏內(nèi)存布局?!請(qǐng)回想聲明的作用,類的內(nèi)存布局是編譯器生成對(duì)象時(shí)必須的,根本不能對(duì)任何使用對(duì)象的代碼隱藏有關(guān)對(duì)象實(shí)現(xiàn)的任何東西,否則編譯器無(wú)法編譯相應(yīng)的代碼。
    那么從語(yǔ)義上來(lái)看。Person映射的不是真實(shí)世界中的人的概念,應(yīng)該是存放某個(gè)數(shù)據(jù)庫(kù)中的某個(gè)記錄人員信息的表中的記錄的緩沖區(qū),那么緩沖區(qū)應(yīng)該具備那三對(duì)Get/Set所代表的功能嗎?緩沖區(qū)是緩沖數(shù)據(jù)用的,緩沖后被其它操作使用,就好像箱子,只是放東西用。故上面的三對(duì)Get/Set沒有存在的必要,而三個(gè)成員變量則不能是private。當(dāng)然,如果Person映射的并不是緩沖區(qū),而在其它的世界中具備像上面那樣表現(xiàn)的語(yǔ)義,則像上面那樣定義就沒有問題,但如果是因?yàn)閷?duì)內(nèi)存布局的封裝而那樣定義類則是大錯(cuò)特錯(cuò)的。
    上面錯(cuò)誤的根本在于沒有理解何謂封裝。為了說(shuō)明封裝,先看下MFC(Microsoft Foundation Class Library——微軟功能類庫(kù),一個(gè)定義了許多類的庫(kù)文件,其中的絕大部分類是封裝設(shè)計(jì)。關(guān)于庫(kù)文件在說(shuō)明SDK時(shí)闡述)中的類CFile的定義。從名字就可看出它映射的是操作系統(tǒng)中文件的概念,但它卻有這樣的成員函數(shù)——CFile::Open、CFile::Close、CFile::Read、CFile::Write,有什么問題?這四個(gè)成員函數(shù)映射的都是對(duì)文件的操作而不是文件所具備的功能,分別為打開文件、關(guān)閉文件、從文件讀數(shù)據(jù)、向文件寫數(shù)據(jù)。這不是和前面說(shuō)的成員函數(shù)的語(yǔ)義相背嗎?上面四個(gè)操作有個(gè)共性,都是施加于文件這個(gè)資源上的操作,可以將它們叫做“被功能”,如文件具有“被打開”的功能,具有“被讀取”的功能,但應(yīng)注意它們實(shí)際并不是文件的功能。
    按照原來(lái)的說(shuō)法,應(yīng)該將文件映射為一個(gè)結(jié)構(gòu),如FILE,然后上面的四個(gè)操作應(yīng)映射成四個(gè)函數(shù),再利用名字空間的功能,如下:
    namespace OFILE
    {
        bool Open( FILE&, … );  bool Close( FILE&, … );
        bool Read( FILE&, … );  bool Write( FILE&, … );
    }
    上面的名字空間OFILE表示里面的四個(gè)函數(shù)都是對(duì)文件的操作,但四個(gè)函數(shù)都帶有一個(gè)FILE&的參數(shù)。回想非靜態(tài)成員函數(shù)都有個(gè)隱藏的參數(shù)this,因此,一個(gè)了不起的想法誕生了。
    將所有對(duì)某種資源的操作的集合看成是一種資源,把它映射成一個(gè)類,則這個(gè)類的對(duì)象就是對(duì)某個(gè)對(duì)象的操作,此法被稱作封裝,而那個(gè)類被稱作包裝類或封裝類。很明顯,包裝類映射的是“對(duì)某種資源的操作”,是一抽象概念,即包裝類的對(duì)象都是無(wú)狀態(tài)對(duì)象(指邏輯上應(yīng)該是無(wú)狀態(tài)對(duì)象,但如果多個(gè)操作間有聯(lián)系,則還是可能有狀態(tài)的,但此時(shí)它的語(yǔ)義也相應(yīng)地有些變化。如多一個(gè)CFile::Flush成員函數(shù),用于刷新緩沖區(qū)內(nèi)容,則此時(shí)就至少有一個(gè)狀態(tài)——緩沖區(qū),還可有一個(gè)狀態(tài)記錄是否已經(jīng)調(diào)用過CFile::Write,沒有則不用刷新)。
    現(xiàn)在應(yīng)能了解封裝的含義了。將對(duì)某種資源的操作封裝成一個(gè)類,此包裝類映射的不是世界中定義的某一“名詞性概念”,而是世界的“動(dòng)詞性概念”或算法中“對(duì)某一概念的操作”這個(gè)人為定出來(lái)的抽象概念。由于包裝類是對(duì)某種資源的操作的封裝,則包裝類對(duì)象一定有個(gè)屬性指明被操作的對(duì)象,對(duì)于MFC中的CFile,就是CFile::m_hFile成員變量(類型為HANDLE),其在包裝類對(duì)象的主要運(yùn)作過程(前面的CFile::Read和CFile::Write)中被讀。
    有什么好處?封裝提供了一種手段以將世界中的部分“動(dòng)詞性概念”轉(zhuǎn)換成對(duì)象,使得程序的架構(gòu)更加簡(jiǎn)單(多條“動(dòng)詞性概念”變成一個(gè)“名詞性概念”,減少了“動(dòng)詞性概念”的數(shù)量),更趨于面向?qū)ο蟮木幊趟枷搿?BR>    但應(yīng)區(qū)別開包裝類對(duì)象和被包裝的對(duì)象。包裝類對(duì)象只是個(gè)外殼,而被包裝的對(duì)象一定是個(gè)具有狀態(tài)的對(duì)象,因?yàn)椴僮骶褪歉淖冑Y源的狀態(tài)。對(duì)于CFile,CFile的實(shí)例是包裝類對(duì)象,其保持著一個(gè)對(duì)被包裝對(duì)象——文件內(nèi)核對(duì)象(Windows操作系統(tǒng)中定義的一種資源,用HANDLE的實(shí)例表征)——的引用,放在CFile::m_hFile中。因此,包裝類對(duì)象是獨(dú)立于被包裝對(duì)象的。即CFile a;,此時(shí)a.m_hFile的值為0或-1,表示其引用的對(duì)象是無(wú)效的,因此如果a.Read( … );將失敗,因?yàn)椴僮魇┘拥馁Y源是無(wú)效的。對(duì)此,就應(yīng)先調(diào)用a.Open( … );以將a和一特定的文件內(nèi)核對(duì)象綁定起來(lái),而調(diào)用a.Close( … );將解除綁定。注意CFile::Close調(diào)用后只是解除了綁定,并不代表a已經(jīng)被銷毀了,因?yàn)閍映射的并不是文件內(nèi)核對(duì)象,而是對(duì)文件內(nèi)核對(duì)象操作的包裝類對(duì)象。
    如果仔細(xì)想想,就會(huì)發(fā)現(xiàn),老虎能夠吃兔子,兔子能夠被吃,那這里應(yīng)該是老虎有個(gè)功能是“吃兔子”還是多個(gè)兔子的包裝類來(lái)封裝“吃兔子”的操作?這其實(shí)不存在任何問題,“老虎吃兔子”和“兔子被吃”完全是兩個(gè)不同的操作,前者涉及兩種資源,后者只涉及一種資源,因此可以同時(shí)實(shí)現(xiàn)兩者,具體應(yīng)視各自在相應(yīng)世界中的語(yǔ)義。如果對(duì)于真實(shí)世界,則可以簡(jiǎn)略地說(shuō)老虎有個(gè)“吃”的功能,可以吃“肉”,而動(dòng)物從“肉”和“自主能動(dòng)性”多重繼承,兔子再?gòu)膭?dòng)物繼承。這里有個(gè)類叫“自主能動(dòng)性”,指動(dòng)物具有意識(shí),能夠自己動(dòng)作,這在C++中的表現(xiàn)就是有成員函數(shù)的類,表示有功能可以被操作,但收音機(jī)也具有調(diào)臺(tái)等功能,難道說(shuō)收音機(jī)也能自己動(dòng)?!這就是世界的意義——運(yùn)轉(zhuǎn)。

(本文是本人以baodi_z的網(wǎng)名原發(fā)表在CSDN的個(gè)人BLOG,原文發(fā)表于 2004年12月09日 2:09 PM )

posted on 2005-09-12 23:35 冷夜 閱讀(2193) 評(píng)論(8)  編輯 收藏 引用 所屬分類: C++ 經(jīng)驗(yàn)與技巧冷夜文摘

Feedback

# re: 關(guān)于封裝--一個(gè)有趣的C++例子 2005-09-13 09:28 atempcode
有什么奇怪。本來(lái)private就是compile time check, 不是 run time check.  回復(fù)  更多評(píng)論
  

# re: 關(guān)于封裝--一個(gè)有趣的C++例子 2005-09-13 20:14 冷夜
呵呵,這個(gè)我沒有研究透,所以剛開始覺得很意外  回復(fù)  更多評(píng)論
  

# re: 關(guān)于封裝--一個(gè)有趣的C++例子 2005-09-13 23:15 可冰
其實(shí)他這個(gè)方式不一定有效,因?yàn)镃++的類成員的內(nèi)存布局可以與聲明的順序不一樣,而不象C的結(jié)構(gòu)中的成員一樣,要完全的一致.所以他這樣的實(shí)現(xiàn)有賴于編譯器的實(shí)現(xiàn),而不能得到語(yǔ)言級(jí)的保證.  回復(fù)  更多評(píng)論
  

# re: 關(guān)于封裝--一個(gè)有趣的C++例子 2005-09-13 23:42 冷夜
樓上說(shuō)的有理  回復(fù)  更多評(píng)論
  

# re: 關(guān)于封裝--一個(gè)有趣的C++例子 2005-09-16 10:42 ffox
class Person
{ private: char m_Name[20]; unsigned long m_Age; bool m_Sex;
public: const char* GetName() const; void SetName( const char* );
unsigned long GetAge() const; void SetAge( unsigned long );
bool GetSex() const; void SetSex( bool );
};
person類的設(shè)計(jì)本來(lái)就有問題,我的理解:把變量放在private中,又在public中對(duì)三個(gè)變量進(jìn)行操作,這樣和把變量聲明稱public又有什么區(qū)別?不都是要對(duì)變量進(jìn)行操作嗎,既然把變量放在private中,就要把對(duì)變量操作的member也同樣放在private中.  回復(fù)  更多評(píng)論
  

# re: 關(guān)于封裝--一個(gè)有趣的C++例子 2005-09-18 08:44 FrameSniper
沒什么可奇怪的!  回復(fù)  更多評(píng)論
  

# re: 關(guān)于封裝--一個(gè)有趣的C++例子 2005-09-18 17:48 可冰
@ffox:
這樣是將對(duì)變量的讀寫操作封裝起來(lái)以接口的形式提供,它在提供了一定的接口一致性.如果以后要在讀寫變量的操作內(nèi)加入其它的操作,那么原有的代碼就可以不加任何修改,只改這樣的接口就行了.也就是對(duì)外部封閉了細(xì)節(jié),使編程簡(jiǎn)單一點(diǎn).
但我也覺得不能用"一刀切"的方式將所有的成員變量都加以這樣的封裝,這樣無(wú)疑會(huì)使代碼增長(zhǎng)(而且可能還有我所不知道的缺點(diǎn)).
所以,可以作如下的總結(jié):
對(duì)于要對(duì)外部提供應(yīng)用的變量,最好以接口的形式提供;而如果只是內(nèi)部用的話,在用途只是用于保存變量的值的話,直接聲明為public會(huì)好一些.
具體的情況還要加以區(qū)別對(duì)待,根據(jù)實(shí)際情況加以應(yīng)用.  回復(fù)  更多評(píng)論
  

# re: 關(guān)于封裝--一個(gè)有趣的C++例子 2007-07-18 17:13 pchobby
看下面阿:
class Date{
private:
int year,month,day; //日期類的 年月日
pubilc:
void setdate(int& y,int& m,int& d) const{
year=y;month=m;day=d; //向變量賦值
}

//假如我想知道現(xiàn)在是什么日期,怎么辦?
//倘若真要想那樣封裝,我怎么得到日期呢?直接放在public下面?!
};

關(guān)于篡改的問題,說(shuō)實(shí)話俺也很驚訝,要知道兩次聲明的可不一樣啊。。。。。  回復(fù)  更多評(píng)論
  

青青草原综合久久大伊人导航_色综合久久天天综合_日日噜噜夜夜狠狠久久丁香五月_热久久这里只有精品
  • <ins id="pjuwb"></ins>
    <blockquote id="pjuwb"><pre id="pjuwb"></pre></blockquote>
    <noscript id="pjuwb"></noscript>
          <sup id="pjuwb"><pre id="pjuwb"></pre></sup>
            <dd id="pjuwb"></dd>
            <abbr id="pjuwb"></abbr>
            欧美精品亚洲| 夜夜嗨一区二区三区| 亚洲欧美日韩国产一区| 你懂的网址国产 欧美| 亚洲嫩草精品久久| 亚洲高清在线观看| 欧美色道久久88综合亚洲精品| 亚洲欧美色婷婷| 一区二区在线视频播放| 野花国产精品入口| 亚洲国产日韩在线一区模特| 国产久一道中文一区| 欧美性片在线观看| 欧美视频精品在线观看| 欧美日韩国产一中文字不卡 | 欧美一区二区视频97| 亚洲午夜伦理| 久久精品人人做人人爽电影蜜月| 亚洲国产成人午夜在线一区| 久久久久久久一区二区三区| 亚洲欧美国内爽妇网| 亚洲一级电影| 亚洲一区二区三区免费在线观看| 亚洲第一区在线观看| 亚洲国产精品99久久久久久久久| 激情综合在线| 国外成人在线| 亚洲国产欧美一区| 在线亚洲一区| 欧美日韩一二三四五区| 久久久久女教师免费一区| 美国成人毛片| 欧美人成在线| 欧美色123| 国产真实乱子伦精品视频| 激情综合色综合久久| 亚洲久久一区二区| 欧美激情一区二区三区在线视频观看 | 久久婷婷麻豆| 欧美精品 国产精品| 欧美视频一区二区在线观看 | 国产精品久久久久一区二区三区| 国产亚洲欧美另类一区二区三区| 国模大胆一区二区三区| 亚洲片国产一区一级在线观看| 国产精品综合| 亚洲精品免费网站| 欧美一区二区三区在线| 裸体一区二区| 亚洲午夜激情在线| 免费亚洲电影在线观看| 国产精品一区毛片| 亚洲乱码视频| 免费观看成人网| 日韩小视频在线观看| 亚洲图片在区色| 久久国产一区| 91久久久久久久久久久久久| 亚洲一区免费在线观看| 久久综合九九| 国产精品美女久久久| 亚洲欧洲在线免费| 亚洲欧美在线一区二区| 亚洲综合色网站| 欧美高清影院| 欧美一区二区三区四区在线观看| 欧美日韩精品一区二区在线播放 | 国产精品99久久久久久www| 久久躁日日躁aaaaxxxx| 国产欧美在线| 亚洲午夜在线视频| 久久大综合网| 亚洲欧美成人一区二区在线电影 | 亚洲精品影视| 欧美久久精品午夜青青大伊人| 国产精品第三页| 一区二区电影免费在线观看| 久久综合色婷婷| 最新国产成人av网站网址麻豆| 欧美一区二区三区在线观看视频| 欧美三级日本三级少妇99| 日韩视频在线观看| 亚洲动漫精品| 欧美大成色www永久网站婷| 亚洲影音先锋| 欧美日韩网址| 在线综合+亚洲+欧美中文字幕| 亚洲第一页在线| 免费一级欧美片在线播放| 在线观看成人网| 免费成人高清视频| 麻豆亚洲精品| 亚洲免费观看高清在线观看| 91久久精品国产91性色 | 欧美一级淫片播放口| 国产情侣一区| 久久偷窥视频| 亚洲国产影院| 亚洲欧洲综合另类在线| 欧美mv日韩mv亚洲| 亚洲美女视频在线观看| 亚洲精品一区二区三区樱花| 欧美视频免费在线| 欧美一级大片在线观看| 亚洲欧美日韩精品久久奇米色影视 | 久久中文字幕一区| 国产精品影音先锋| 欧美激情久久久久| 狂野欧美性猛交xxxx巴西| 欧美激情精品久久久久久| 亚洲毛片视频| 欧美在线看片| 亚洲中无吗在线| 欧美激情视频在线免费观看 欧美视频免费一| 亚洲在线视频网站| 欧美黑人在线观看| 农村妇女精品| 国产综合亚洲精品一区二| 一本一本久久a久久精品综合麻豆| 狠狠综合久久av一区二区老牛| 在线一区二区三区四区| 99国产精品国产精品久久| 久久久久网址| 久久久999精品免费| 国产精品欧美久久久久无广告| 91久久在线观看| 亚洲国产成人一区| 久久精品综合网| 久久免费观看视频| 国产在线不卡| 久久黄色小说| 免费在线欧美视频| 在线欧美福利| 美女999久久久精品视频| 久久久一本精品99久久精品66| 国产精品视频男人的天堂| 亚洲欧美日韩精品| 亚洲天堂第二页| 亚洲欧美制服另类日韩| 久久综合图片| 久久久久久久999精品视频| 久久av二区| 国产女优一区| 性色av一区二区怡红| 久久精品国产77777蜜臀| 国产亚洲福利| 久久资源av| 亚洲激情黄色| 亚洲一区二区欧美| 国产精品美女久久久浪潮软件| 一区二区三区视频在线| 香蕉久久夜色| 国产一区深夜福利| 欧美1区视频| 亚洲精品一区二区三区不| 亚洲一区二区四区| 国产美女精品人人做人人爽| 久久www成人_看片免费不卡| 另类激情亚洲| 亚洲欧美日韩另类| 欧美福利影院| 国产综合自拍| 国产精自产拍久久久久久蜜| 美女在线一区二区| 一区二区三区偷拍| 亚洲无亚洲人成网站77777| 欧美三级视频在线观看| 亚洲午夜精品一区二区三区他趣| 午夜视频在线观看一区二区| 国产亚洲精品一区二555| 久久久视频精品| 亚洲美女在线看| 欧美一区二区三区日韩| 一区二区三区在线不卡| 欧美日韩国产电影| 亚洲欧美日韩高清| 亚洲福利视频一区| 亚洲欧美日韩综合| 欧美日韩免费一区二区三区| 亚洲一区二区成人在线观看| 亚洲激情网站| 免费不卡中文字幕视频| 亚洲二区在线| 亚洲欧洲三级电影| 欧美大片一区二区| 亚洲素人在线| 欧美1区2区| 午夜国产一区| 亚洲美女淫视频| 国产一区二区三区在线观看精品| 牛人盗摄一区二区三区视频| 亚洲一二三区在线观看| 欧美成人一二三| 先锋影音一区二区三区| 亚洲日韩成人| 一区福利视频| 国产综合婷婷| 国产麻豆精品theporn| 欧美激情亚洲| 一区二区成人精品|