C++类与对象概念详解
一、 簡介
1.類用于指定對象的形式,它包含了數(shù)據(jù)表示法和用于處理數(shù)據(jù)的方法。類中的數(shù)據(jù)和方法稱為類的成員。函數(shù)在一個類中被稱為類的成員。
2.類提供了對象的藍圖,所以基本上,對象是根據(jù)類來創(chuàng)建的。聲明類的對象,就像聲明基本類型的變量一樣。
二、類成員函數(shù)
1.類的成員函數(shù)是指那些把定義和原型寫在類定義內(nèi)部的函數(shù),就像類定義中的其他變量一樣。類成員函數(shù)是類的一個成員,它可以操作類的任意對象,可以訪問對象中的所有成員。
2.成員函數(shù)可以定義在類定義內(nèi)部,或者單獨使用范圍解析運算符 ::?來定義。在類定義中定義的成員函數(shù)把函數(shù)聲明為內(nèi)聯(lián)的,即便沒有使用 inline 標識符。
1 class Box2 {3 public:4 double length; // 長度5 double breadth; // 寬度6 double height; // 高度7 8 double getVolume(void)9 { 10 return length * breadth * height; 11 } 12 };或者
1 double Box::getVolume(void) 2 { 3 return length * breadth * height; 4 }三、構(gòu)造函數(shù)
1.類的構(gòu)造函數(shù)是類的一種特殊的成員函數(shù),它會在每次創(chuàng)建類的新對象時執(zhí)行。
2.構(gòu)造函數(shù)的名稱與類的名稱是完全相同的,并且不會返回任何類型,也不會返回 void。構(gòu)造函數(shù)可用于為某些成員變量設(shè)置初始值。
四、析構(gòu)函數(shù)
1.類的析構(gòu)函數(shù)是類的一種特殊的成員函數(shù),它會在每次刪除所創(chuàng)建的對象時執(zhí)行。
2.析構(gòu)函數(shù)的名稱與類的名稱是完全相同的,只是在前面加了個波浪號(~)作為前綴,它不會返回任何值,也不能帶有任何參數(shù)。析構(gòu)函數(shù)有助于在跳出程序(比如關(guān)閉文件、釋放內(nèi)存等)前釋放資源。
注:刪除類對象時會調(diào)用析構(gòu)函數(shù);程序跳出對象作用域時會調(diào)用析構(gòu)函數(shù)。
五、拷貝構(gòu)造函數(shù)
拷貝構(gòu)造函數(shù)是一種特殊的構(gòu)造函數(shù),它在創(chuàng)建對象時,是使用同一類中之前創(chuàng)建的對象來初始化新創(chuàng)建的對象。拷貝構(gòu)造函數(shù)通常用于:
-
通過使用另一個同類型的對象來初始化新創(chuàng)建的對象。
1 Box box2=box1; -
復(fù)制對象把它作為參數(shù)傳遞給函數(shù)。
1 printwidth(box1); -
復(fù)制對象,并從函數(shù)返回這個對象。
如果在類中沒有定義拷貝構(gòu)造函數(shù),編譯器會自行定義一個。如果類帶有指針變量,并有動態(tài)內(nèi)存分配,則它必須有一個拷貝構(gòu)造函數(shù)。拷貝構(gòu)造函數(shù)的最常見形式如下:
1 classname (const classname &obj) {//obj 是一個對象引用,該對象是用于初始化另一個對象的。 2 // 構(gòu)造函數(shù)的主體 3 }六、友元函數(shù)
類的友元函數(shù)是定義在類外部,但有權(quán)訪問類的所有私有(private)成員和保護(protected)成員。盡管友元函數(shù)的原型有在類的定義中出現(xiàn)過,但是友元函數(shù)并不是成員函數(shù)。
友元可以是一個函數(shù),該函數(shù)被稱為友元函數(shù);友元也可以是一個類,該類被稱為友元類,在這種情況下,整個類及其所有成員都是友元。
如果要聲明函數(shù)為一個類的友元,需要在類定義中該函數(shù)原型前使用關(guān)鍵字?friend,如下所示:
1 class Box 2 { 3 double width; 4 public: 5 double length; 6 friend void printWidth( Box box ); 7 void setWidth( double wid ); 8 };聲明類 ClassTwo 的所有成員函數(shù)作為類 ClassOne 的友元,需要在類 ClassOne 的定義中放置如下聲明:
1 friend class ClassTwo;七、內(nèi)聯(lián)函數(shù)
1.C++?內(nèi)聯(lián)函數(shù)是通常與類一起使用。如果一個函數(shù)是內(nèi)聯(lián)的,那么在編譯時,編譯器會把該函數(shù)的代碼副本放置在每個調(diào)用該函數(shù)的地方。
2.對內(nèi)聯(lián)函數(shù)進行任何修改,都需要重新編譯函數(shù)的所有客戶端,因為編譯器需要重新更換一次所有的代碼,否則將會繼續(xù)使用舊的函數(shù)。
3.如果想把一個函數(shù)定義為內(nèi)聯(lián)函數(shù),則需要在函數(shù)名前面放置關(guān)鍵字?inline,在調(diào)用函數(shù)之前需要對函數(shù)進行定義。如果已定義的函數(shù)多于一行,編譯器會忽略 inline 限定符。
4.在類定義中的定義的函數(shù)都是內(nèi)聯(lián)函數(shù),即使沒有使用?inline?說明符。
Tip:
只有當函數(shù)只有 10 行甚至更少時才將其定義為內(nèi)聯(lián)函數(shù).
定義: 當函數(shù)被聲明為內(nèi)聯(lián)函數(shù)之后, 編譯器會將其內(nèi)聯(lián)展開, 而不是按通常的函數(shù)調(diào)用機制進行調(diào)用.
優(yōu)點: 當函數(shù)體比較小的時候, 內(nèi)聯(lián)該函數(shù)可以令目標代碼更加高效. 對于存取函數(shù)以及其它函數(shù)體比較短, 性能關(guān)鍵的函數(shù), 鼓勵使用內(nèi)聯(lián).
缺點: 濫用內(nèi)聯(lián)將導致程序變慢. 內(nèi)聯(lián)可能使目標代碼量或增或減, 這取決于內(nèi)聯(lián)函數(shù)的大小. 內(nèi)聯(lián)非常短小的存取函數(shù)通常會減少代碼大小, 但內(nèi)聯(lián)一個相當大的函數(shù)將戲劇性的增加代碼大小. 現(xiàn)代處理器由于更好的利用了指令緩存, 小巧的代碼往往執(zhí)行更快。
結(jié)論: 一個較為合理的經(jīng)驗準則是, 不要內(nèi)聯(lián)超過 10 行的函數(shù). 謹慎對待析構(gòu)函數(shù), 析構(gòu)函數(shù)往往比其表面看起來要更長, 因為有隱含的成員和基類析構(gòu)函數(shù)被調(diào)用!
另一個實用的經(jīng)驗準則: 內(nèi)聯(lián)那些包含循環(huán)或 switch 語句的函數(shù)常常是得不償失 (除非在大多數(shù)情況下, 這些循環(huán)或 switch 語句從不被執(zhí)行).
有些函數(shù)即使聲明為內(nèi)聯(lián)的也不一定會被編譯器內(nèi)聯(lián), 這點很重要; 比如虛函數(shù)和遞歸函數(shù)就不會被正常內(nèi)聯(lián). 通常, 遞歸函數(shù)不應(yīng)該聲明成內(nèi)聯(lián)函數(shù).(遞歸調(diào)用堆棧的展開并不像循環(huán)那么簡單, 比如遞歸層數(shù)在編譯時可能是未知的, 大多數(shù)編譯器都不支持內(nèi)聯(lián)遞歸函數(shù)). 虛函數(shù)內(nèi)聯(lián)的主要原因則是想把它的函數(shù)體放在類定義內(nèi), 為了圖個方便, 抑或是當作文檔描述其行為, 比如精短的存取函數(shù).
?八、this指針
在 C++ 中,每一個對象都能通過?this?指針來訪問自己的地址。this?指針是所有成員函數(shù)的隱含參數(shù)。因此,在成員函數(shù)內(nèi)部,它可以用來指向調(diào)用對象。
友元函數(shù)沒有?this?指針,因為友元不是類的成員。只有成員函數(shù)才有?this?指針。
下面的實例有助于更好地理解 this 指針的概念:
1 #include <iostream>2 3 using namespace std;4 5 class Box6 {7 public:8 // 構(gòu)造函數(shù)定義9 Box(double l=2.0, double b=2.0, double h=2.0) 10 { 11 cout <<"Constructor called." << endl; 12 length = l; 13 breadth = b; 14 height = h; 15 } 16 double Volume() 17 { 18 return length * breadth * height; 19 } 20 int compare(Box box) 21 { 22 return this->Volume() > box.Volume(); 23 } 24 private: 25 double length; // Length of a box 26 double breadth; // Breadth of a box 27 double height; // Height of a box 28 }; 29 30 int main(void) 31 { 32 Box Box1(3.3, 1.2, 1.5); // Declare box1 33 Box Box2(8.5, 6.0, 2.0); // Declare box2 34 35 if(Box1.compare(Box2)) 36 { 37 cout << "Box2 is smaller than Box1" <<endl; 38 } 39 else 40 { 41 cout << "Box2 is equal to or larger than Box1" <<endl; 42 } 43 return 0; 44 }編譯執(zhí)行結(jié)果
1 Constructor called. 2 Constructor called. 3 Box2 is equal to or larger than Box1九、指向類的指針
一個指向 C++ 類的指針與指向結(jié)構(gòu)的指針類似,訪問指向類的指針的成員,需要使用成員訪問運算符 ->,就像訪問指向結(jié)構(gòu)的指針一樣。與所有的指針一樣,您必須在使用指針之前,對指針進行初始化。
十、類的靜態(tài)成員
1.使用?static?關(guān)鍵字可以把類成員定義為靜態(tài)的。當我們聲明類的成員為靜態(tài)時,這意味著無論創(chuàng)建多少個類的對象,靜態(tài)成員都只有一個副本。
2.靜態(tài)成員在類的所有對象中是共享的。如果不存在其他的初始化語句,在創(chuàng)建第一個對象時,所有的靜態(tài)數(shù)據(jù)都會被初始化為零。
3.不能把靜態(tài)成員的初始化放置在類的定義中,但是可以在類的外部通過使用范圍解析運算符?::?來重新聲明靜態(tài)變量從而對它進行初始化
如果把函數(shù)成員聲明為靜態(tài)的,就可以把函數(shù)與類的任何特定對象獨立開來。靜態(tài)成員函數(shù)即使在類對象不存在的情況下也能被調(diào)用,靜態(tài)函數(shù)只要使用類名加范圍解析運算符?::?就可以訪問。
靜態(tài)成員函數(shù)只能訪問靜態(tài)成員數(shù)據(jù)、其他靜態(tài)成員函數(shù)和類外部的其他函數(shù)。
靜態(tài)成員函數(shù)有一個類范圍,他們不能訪問類的 this 指針。您可以使用靜態(tài)成員函數(shù)來判斷類的某些對象是否已被創(chuàng)建。
靜態(tài)成員函數(shù)與普通成員函數(shù)的區(qū)別:
- 靜態(tài)成員函數(shù)沒有 this 指針,只能訪問靜態(tài)成員(包括靜態(tài)成員變量和靜態(tài)成員函數(shù))。
- 普通成員函數(shù)有 this 指針,可以訪問類中的任意成員;而靜態(tài)成員函數(shù)沒有 this 指針。
編譯執(zhí)行結(jié)果
1 Inital Stage Count: 0 2 Constructor called. 3 Constructor called. 4 Final Stage Count: 2十一、綜合測試實驗
執(zhí)行測試代碼,及其輸出結(jié)果如下所示:
1 #include <iostream>2 3 using namespace std;4 5 class Box{6 double width;//默認訪問修飾符為private7 double *high;//【當類成員變量是指針時,需在構(gòu)造函數(shù)和拷貝構(gòu)造函數(shù)中為其申請內(nèi)存,并在析構(gòu)函數(shù)中刪除內(nèi)存】8 public:9 void setWidth(double wid); 10 void setHigh(double hig); 11 double getHigh( void ); 12 Box(double wid, double hig);//構(gòu)造函數(shù) 13 ~Box(void);//析構(gòu)函數(shù) 14 Box(const Box &obj);//拷貝構(gòu)造函數(shù) 15 16 friend void printwidth(Box box);//友元函數(shù) 17 }; 18 void Box::setWidth(double wid) 19 { 20 width = wid; 21 } 22 void Box::setHigh(double hig) 23 { 24 *high = hig; 25 } 26 double Box::getHigh( void ) 27 { 28 return *high; 29 } 30 Box::Box(double wid, double hig) 31 { 32 cout << "調(diào)用構(gòu)造函數(shù)" << endl; 33 width = wid; 34 high = new double;//申請內(nèi)存 35 *high = hig; 36 } 37 Box::~Box(void) 38 { 39 cout << "調(diào)用析構(gòu)函數(shù)并釋放內(nèi)存" << endl; 40 delete high;//釋放內(nèi)存 41 } 42 Box::Box(const Box &obj) 43 { 44 cout << "調(diào)用拷貝構(gòu)造函數(shù)" << endl; 45 width = obj.width; 46 high = new double;//申請內(nèi)存 47 *high = *obj.high; 48 } 49 //友元函數(shù)不是類成員變量,但需在類中聲明 50 void printwidth(Box box) 51 { 52 cout << "調(diào)用友元函數(shù)" << endl; 53 cout << "width of box :" << box.width << endl; 54 } 55 void printhigh(Box obj) 56 { 57 cout << "high of box :" << obj.getHigh() << endl; 58 } 59 //程序主函數(shù) 60 int main( ) 61 { 62 Box box1(12,15); 63 Box box2=box1; 64 65 //輸出width、high 66 printwidth(box1); 67 printhigh(box1); 68 printwidth(box2); 69 printhigh(box2); 70 71 //設(shè)置width、high 72 box2.setWidth(13); 73 box2.setHigh(16); 74 75 //輸出width、high 76 printwidth(box1); 77 printhigh(box1); 78 printwidth(box2); 79 printhigh(box2); 80 81 return 0;//調(diào)用析構(gòu)函數(shù)(釋放box1、box2) 82 }總結(jié)
以上是生活随笔為你收集整理的C++类与对象概念详解的全部內(nèi)容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: c语言-指针的本质和使用
- 下一篇: QTCreator使用MSVC编译开发配