自拍偷在线精品自拍偷,亚洲欧美中文日韩v在线观看不卡

C++基礎(chǔ)之類的詳細(xì)介紹(一)

開(kāi)發(fā) 后端
本文介紹的是C++中的類,針對(duì)初學(xué)者而言,這是很好的教程。希望對(duì)大家有幫助,一起來(lái)看。

C++中,提到類型定義符前還可以書(shū)寫(xiě)class,即類型的自定義類型(簡(jiǎn)稱類),它和結(jié)構(gòu)根本沒(méi)有區(qū)別(僅有一點(diǎn)小小的區(qū)別,下篇說(shuō)明),而之所以還要提供一個(gè)class,實(shí)際是由于C++是從C擴(kuò)展而成,其中的class是C++自己提出的一個(gè)很重要的概念,只是為了與C語(yǔ)言兼容而保留了struct這個(gè)關(guān)鍵字。

暫時(shí)可以先認(rèn)為類較結(jié)構(gòu)的長(zhǎng)足進(jìn)步就是多了成員函數(shù)這個(gè)概念(雖然結(jié)構(gòu)也可以有成員函數(shù)),在了解成員函數(shù)之前,先來(lái)看一種語(yǔ)義需求。

操作與資源

程序主要是由操作和被操作的資源組成,操作的執(zhí)行者就是CPU,這很正常,但有時(shí)候的確存在一些需要,需要表現(xiàn)是某個(gè)資源操作了另一個(gè)資源(暫時(shí)稱作操作者),比如游戲中,經(jīng)常出現(xiàn)的就是要映射怪物攻擊了玩家。之所以需要操作者,一般是因?yàn)檫@個(gè)操作也需要修改操作者或利用操作者記錄的一些信息來(lái)完成操作,比如怪物的攻擊力來(lái)決定玩家被攻擊后的狀態(tài)。這種語(yǔ)義就表現(xiàn)為操作者具有某些功能。為了實(shí)現(xiàn)上面的語(yǔ)義,如原來(lái)所說(shuō)進(jìn)行映射,先映射怪物和玩家分別為結(jié)構(gòu),如下:

 

  1. struct Monster { float Life; float Attack; float Defend; };  
  2. struct Player { float Life; float Attack; float Defend; }; 

 

上面的攻擊操作就可以映射為void MonsterAttackPlayer( Monster &mon, Player &pla );。注意這里期望通過(guò)函數(shù)名來(lái)表現(xiàn)操作者,但和前篇說(shuō)的將過(guò)河方案起名為sln一樣,屬于一種本末倒置,因?yàn)檫@個(gè)語(yǔ)義應(yīng)該由類型來(lái)表現(xiàn),而不是函數(shù)名。為此,C++提供了成員函數(shù)的概念。

成員函數(shù)

與之前一樣,在類型定義符中書(shū)寫(xiě)函數(shù)的聲明語(yǔ)句將定義出成員函數(shù),如下:

 

  1. struct ABC { long a; void AB( long ); }; 

 

上面就定義了一個(gè)映射元素——第一個(gè)變量ABC::a,類型為long ABC::;以及聲明了一個(gè)映射元素——第二個(gè)函數(shù)ABC::AB,類型為void ( ABC:: )( long )。類型修飾符ABC::在此修飾了函數(shù)ABC::AB,表示其為函數(shù)類型的偏移類型,即是一相對(duì)值。但由于是函數(shù),意義和變量不同,即其依舊映射的是內(nèi)存中的地址(代碼的地址),但由于是偏移類型,也就是相對(duì)的,即是不完整的,因此不能對(duì)它應(yīng)用函數(shù)操作符,如:

  1. ABC::AB( 10 ); 

 

這里將錯(cuò)誤,因?yàn)锳BC::AB是相對(duì)的,其相對(duì)的東西不是如成員變量那樣是個(gè)內(nèi)存地址,而是一個(gè)結(jié)構(gòu)指針類型的參數(shù),參數(shù)名一定為this,這是強(qiáng)行定義的,后面說(shuō)明。

注意由于其名字為ABC::AB,而上面僅僅是對(duì)其進(jìn)行了聲明,要定義它,仍和之前的函數(shù)定義一樣,如下:

 

  1. void ABC::AB( long d ) { this->a = d; } 

 

應(yīng)注意上面函數(shù)的名字為ABC::AB,但和前篇說(shuō)的成員變量一樣,不能直接書(shū)寫(xiě)long ABC::a;,也就不能直接如上書(shū)寫(xiě)函數(shù)的定義語(yǔ)句(至少函數(shù)名為ABC::AB就不符合標(biāo)識(shí)符規(guī)則),而必須要通過(guò)類型定義符“{}”先定義自定義類型,然后再書(shū)寫(xiě),這會(huì)在后面說(shuō)明聲明時(shí)詳細(xì)闡述。

注意上面使用了this這個(gè)關(guān)鍵字,其類型為ABC*,由編譯器自動(dòng)生成,即上面的函數(shù)定義實(shí)際等同于

  1. void ABC::AB( ABC *thislong d ) { this->a = d; } 

 

而之所以要省略this參數(shù)的聲明而由編譯器來(lái)代勞是為了在代碼上體現(xiàn)出前面提到的語(yǔ)義(即成員的意義),這也是為什么稱ABC::AB是函數(shù)類型的偏移類型,它是相對(duì)于這個(gè)this參數(shù)而言的,如何相對(duì),如下:

  1. ABC a, b, c;   
  2. a.ABC::AB( 10 );   
  3. b.ABC::AB( 12 );   
  4. c.AB( 14 ); 

 

上面利用成員操作符調(diào)用ABC::AB,注意執(zhí)行后,a.a、b.a和c.a的值分別為10、12和14,即三次調(diào)用ABC::AB,但通過(guò)成員操作符而導(dǎo)致三次的this參數(shù)的值并不相同,并進(jìn)而得以修改三個(gè)ABC變量的成員變量a。注意上面書(shū)寫(xiě)

  1. a.ABC::AB( 10 ); 

 

和成員變量一樣,由于左右類型必須對(duì)應(yīng),因此也可

  1. a.AB( 10 ); 

 

還應(yīng)注意上面在定義ABC::AB時(shí),在函數(shù)體內(nèi)書(shū)寫(xiě)

  1. this->a = d; 

 

同上,由于類型必須對(duì)應(yīng)的關(guān)系,即this必須是相應(yīng)自定義類型的指針,所以也可省略this->的書(shū)寫(xiě),進(jìn)而有

  1. void ABC::AB( long d ) { a = d; } 

 

注意這里成員操作符的作用,其不再如成員變量時(shí)返回相應(yīng)成員變量類型的數(shù)字,而是返回一函數(shù)類型的數(shù)字,但不同的就是這個(gè)函數(shù)類型是無(wú)法用語(yǔ)法表示出來(lái)的,即C++并沒(méi)有提供任何關(guān)鍵字或類型修飾符來(lái)表現(xiàn)這個(gè)返回的類型(VC內(nèi)部提供了__thiscall這個(gè)類型修飾符進(jìn)行表示,不過(guò)寫(xiě)代碼時(shí)依舊不能使用,只是編譯器內(nèi)部使用)。

也就是說(shuō),當(dāng)成員操作符右側(cè)接的是函數(shù)類型的偏移類型的數(shù)字時(shí),返回一個(gè)函數(shù)類型的數(shù)字(表示其可被施以函數(shù)操作符),函數(shù)的類型為偏移類型中給出的類型,但這個(gè)類型無(wú)法表現(xiàn)。即a.AB將返回一個(gè)數(shù)字,這個(gè)數(shù)字是函數(shù)類型,在VC內(nèi)部其類型為void ( __thiscall ABC:: )( long ),但這個(gè)類型在C++中是非法的。

C++并沒(méi)有提供類似__thiscall這樣的關(guān)鍵字以修飾類型,因?yàn)檫@個(gè)類型是要求編譯器遇到函數(shù)操作符和成員操作符時(shí),如

  1. a.AB( 10 ); 

 

要將成員操作符左側(cè)的地址作為函數(shù)調(diào)用的第一個(gè)參數(shù)傳進(jìn)去,然后再傳函數(shù)操作符中給出的其余各參數(shù)。即這個(gè)類型是針對(duì)同時(shí)出現(xiàn)函數(shù)操作符和成員操作符這一特定情況,給編譯器提供一些信息以生成正確的代碼,而不用于修飾數(shù)字(修飾數(shù)字就要求能應(yīng)付所有情況)。即類型是用于修飾數(shù)字的,而這個(gè)類型不能修飾數(shù)字,因此C++并未提供類似__thiscall的關(guān)鍵字。

和之前一樣,由于ABC::AB映射的是一個(gè)地址,而不是一個(gè)偏移值,因此可以

  1. ABC::AB; 

 

但不能

  1. ABC::a; 

 

因?yàn)楹笳呤瞧浦?。根?jù)類型匹配,很容易就知道也可有:

 

  1. void ( ABC::*p )( long ) = ABC::AB;  
  2. 或  
  3. void ( ABC::*p )( long ) = &ABC::AB; 

 

進(jìn)而就有:

  1. void ( ABC::**pP )( long ) = &p; ( c.**pP )( 10.0f ); 

 

之所以加括號(hào)是因?yàn)楹瘮?shù)操作符的優(yōu)先級(jí)較“*”高。再回想前篇說(shuō)過(guò)指針類型的轉(zhuǎn)換只是類型變化,數(shù)值不變(下篇說(shuō)明數(shù)值變化的情況),因此可以有如下代碼,這段代碼毫無(wú)意義,在此僅為加深對(duì)成員函數(shù)的理解。

 

  1. struct ABC { long a; void AB( long ); };  
  2. void ABC::AB( long d )  
  3. {  
  4.   this->a = d;  
  5. }  
  6. struct AB  
  7. {  
  8.   short a, b;  
  9.   void ABCD( short tem1, short tem2 );  
  10.   void ABC( long tem );  
  11. };  
  12. void AB::ABCD( short tem1, short tem2 )  
  13. {  
  14.   a = tem1; b = tem2;  
  15. }  
  16. void AB::ABC( long tem )  
  17. {  
  18.   a = short( tem / 10 );  
  19.   b = short( tem - tem / 10 );  
  20. }  
  21. void main()  
  22. {  
  23.   ABC a, b, c; AB d;  
  24.   ( c.*( void ( ABC::* )( long ) )&AB::ABC )( 43 );  
  25.   ( b.*( void ( ABC::* )( long ) )&AB::ABCD )( 0XABCDEF12 );  
  26.   ( d.*( void ( AB::* )( shortshort ) )ABC::AB )( 0XABCD, 0XEF12 );  

 

上面執(zhí)行后,c.a為0X00270004,b.a為0X0000EF12,d.a為0XABCD,d.b為0XFFFF。對(duì)于c的函數(shù)調(diào)用,由于 AB::ABC映射的地址被直接轉(zhuǎn)換類型進(jìn)而直接被使用,因此程序?qū)⑻紸B::ABC處的

  1. a = short( tem / 10 ); 

 

開(kāi)始執(zhí)行,而參數(shù)tem映射的是傳遞參數(shù)的內(nèi)存的首地址,并進(jìn)而用long類型解釋而得到tem為43,然后執(zhí)行。

注意

  1. b = short( tem - tem / 10 ); 

 

實(shí)際是

  1. this->b = short( tem - tem / 10 ); 

 

而this的值為c對(duì)應(yīng)的地址,但在這里被認(rèn)為是AB*類型(因?yàn)樵诤瘮?shù)AB::ABC的函數(shù)體內(nèi)),所以才能this->b正常(ABC結(jié)構(gòu)中沒(méi)有b這個(gè)成員變量),而b的偏移為2,所以上句執(zhí)行完后將結(jié)果39存放到c的地址加2所對(duì)應(yīng)的內(nèi)存,并且以short類型解釋而得到的16位的二進(jìn)制數(shù)存放。

對(duì)于

  1. a = short( tem / 10 ); 

 

也做同樣事情,故最后得c.a的值為0X0027004(十進(jìn)制39轉(zhuǎn)成十六進(jìn)制為0X27)。

同樣,對(duì)于b的調(diào)用,程序?qū)⑻紸B::ABCD,但生成的b的調(diào)用代碼時(shí),將參數(shù)0XABCDEF12按照參數(shù)類型為long的格式記錄在傳遞參數(shù)的內(nèi)存中,然后跳到AB::ABCD。但編譯AB::ABCD時(shí)又按照參數(shù)為兩個(gè)short類型來(lái)映射參數(shù)tem1和tem2對(duì)應(yīng)的地址,因此容易想到 tem1的值將為0XEF12,tem2的值為0XABCD,但實(shí)際并非如此。

下一篇>>

責(zé)任編輯:于鐵 來(lái)源: 互聯(lián)網(wǎng)
相關(guān)推薦

2011-07-14 16:56:21

2011-07-14 17:02:09

C++指針

2011-06-21 10:37:56

const

2011-07-14 23:27:05

C++引用

2011-07-14 17:17:21

C++指針

2011-07-20 13:57:06

C++STL

2011-07-20 15:58:53

C++引用

2011-07-13 16:49:59

C++

2011-07-20 13:57:06

C++STL

2011-07-15 10:08:11

C++運(yùn)算符重載

2023-12-18 11:15:03

2011-07-20 16:43:34

C++

2011-07-13 11:12:43

C++MFC

2010-01-11 09:56:07

C++編程實(shí)例

2011-07-20 14:12:48

2010-01-19 13:17:05

C++數(shù)據(jù)類型

2011-06-21 15:00:07

JAVAC++

2011-07-20 17:16:50

C++重載函數(shù)

2009-08-13 15:40:28

C#基礎(chǔ)知識(shí)

2020-09-28 08:12:59

CC++時(shí)間
點(diǎn)贊
收藏

51CTO技術(shù)棧公眾號(hào)