日韩性视频-久久久蜜桃-www中文字幕-在线中文字幕av-亚洲欧美一区二区三区四区-撸久久-香蕉视频一区-久久无码精品丰满人妻-国产高潮av-激情福利社-日韩av网址大全-国产精品久久999-日本五十路在线-性欧美在线-久久99精品波多结衣一区-男女午夜免费视频-黑人极品ⅴideos精品欧美棵-人人妻人人澡人人爽精品欧美一区-日韩一区在线看-欧美a级在线免费观看

歡迎訪問 生活随笔!

生活随笔

當前位置: 首頁 > 编程语言 > c/c++ >内容正文

c/c++

C++中类(class)和结构(struct)的区别

發布時間:2023/12/8 c/c++ 33 豆豆
生活随笔 收集整理的這篇文章主要介紹了 C++中类(class)和结构(struct)的区别 小編覺得挺不錯的,現在分享給大家,幫大家做個參考.

類描述看上去很像包含成員函數以及public和private可見性標簽的結構聲明,實際上,C++對結構進行了擴展,使之具有與類相同的特性。它們之間的唯一區別是:結構的默認訪問類型是public而類的默認訪問類型為private。在C++中通常使用類來實現類描述,而把結構限制為只表示純粹的數據對象(常被稱為普通老數據POD(Plain Old Data)結構,)。

C和C++中結構體的不同:

  • C語言中的結構體不能為空,否則會報錯
  • C語言中的結構體只涉及到數據結構,而不涉及到算法,也就是說在C中數據結構和算法是分離的。換句話說就是C語言中的結構體只能定義成員變量,但是不能定義成員函數。
  • 在C++中既可以定義成員變量又可以定義成員函數, C++中的結構體和類體現了數據結構和算法的結合。
  • 雖然C語言的結構體中不能定義成員函數,但是卻可以定義函數指針,不過函數指針本質上不是函數而是指針,所以總的來說C語言中的結構體只是一個復雜數據類型 ,只能定義成員變量,不能定義成員函數,不能用于面向對象編程。
  • 在 C 中,必須顯式使用 struct 關鍵字來聲明結構。 在 c + + 中,不需要在 struct 定義類型后使用關鍵字。

C++中類和結構

  • 結構是實值類型(Value Types),而類則是引用類型(Reference Types)。
  • 結構使用棧存儲(Stack Allocation),而類使用堆存儲(Heap Allocation)。

概念:class和struct的語法基本相同,從聲明到使用,都很相似,但是struct的約束要比class多,理論上,struct能做到的class都能做到,但class能做到的stuct卻不一定做的到。
類型:struct是值類型,class是引用類型,因此它們具有所有值類型和引用類型之間的差異。
效率:由于棧的執行效率要比堆的執行效率高,但是棧資源卻很有限,不適合處理邏輯復雜的大對象,因此struct常用來處理作為基類型對待的小對象,而class來處理某個商業邏輯。
總結:
(1) 在表示諸如點、矩形等主要用來存儲數據的輕量級對象時,首選struct。

(2) 在表示數據量大、邏輯復雜的大對象時,首選class。

(3) 在表現抽象和多級別的對象層次時,class是最佳選擇

如果用C語言實現一個類似面向對象的類

// 寫法一 #include <stdio.h> typedef struct Actress {int height; // 身高int weight; // 體重int age; // 年齡(注意,這不是數據庫,不必一定存儲生日)void (*desc)(struct Actress*); } Actress;void profile(Actress* obj) {printf("height:%d weight:%d age:%d\n", obj->height, obj->weight, obj->age); }int main() {Actress a;a.height = 168;a.weight = 50;a.age = 20;a.desc = profile;a.desc(&a);return 0; }

想達到面向對象中數據和操作封裝到一起的效果,只能給struct里面添加函數指針,然后給函數指針賦值。在C語言的項目中你很少會看到這種寫法,主要原因就是函數指針是有空間成本的。一般會按照如下的方法寫:

// 寫法二 #include <stdio.h> typedef struct Actress {int height; // 身高int weight; // 體重int age; // 年齡(注意,這不是數據庫,不必一定存儲生日)} Actress;void desc(Actress* obj) {printf("height:%d weight:%d age:%d\n", obj->height, obj->weight, obj->age); }int main() {Actress a;a.height = 168;a.weight = 50;a.age = 20;desc(&a);return 0; }:

再看一個普通的C++類:

// 寫法二 #include <stdio.h> class Actress { public:int height; // 身高int weight; // 體重int age; // 年齡(注意,這不是數據庫,不必一定存儲生日)void desc() {printf("height:%d weight:%d age:%d\n", height, weight, age);}};int main() {Actress a;a.height = 168;a.weight = 50;a.age = 20;a.desc();return 0; }

看著像寫法一?其實相當于寫法二。C++編譯器實際會幫你生成一個類似C語言寫法二的形式(這也算是C++ zero overhead指導方針的一個體現)。看到這里就明白了:C++中類和操作的封裝只是對于程序員而言的。而編譯器編譯之后其實還是面向過程的代碼。編譯器幫你給成員函數增加一個額外的類指針參數,運行期間傳入對象實際的指針。類的數據(成員變量)和操作(成員函數)其實還是分離的。
每個函數都有地址(指針),不管是全局函數還是成員函數在編譯之后幾乎類似。

C++結構體和類總結

  • 結構體和類最大的區別就是前者訪問控制默認為public,而類的默認訪問控制是private。而對于public,private,protected的訪問控制都是在編譯期間由編譯器檢查的,編譯通過后,程序執行過程中就不存在什么訪問限制了。籠統一點講,它們在底層只是類型名稱不同,原理都相同。
  • 類與對象,類是一個抽象的概念,而對象則是這個抽象概念里的一個具體實例。(如人–CXX…)類一般由數據成員函數成員組成,而具體對象大小的計算只看數據成員,函數成員屬于執行代碼,不屬于類對象的數據。除本身外,類中的數據成員可以是任何已知的數據類型。
  • 為什么類中不能定義自身的對象呢?因為類在實例化時,必須要知道它的大小,而如果有自身,會形成遞歸定義,沒有出口。但注意自身的指針類型是可以的,因為任何類型的指針大小是已知的。
  • 類對象大小一般就是數據成員大小之和,但也有些特殊情況不符合這個公式。(1)空類,至少占1字節大小,而不是不占內存空間,如果不占內存大小,那么空類就無法實例化。但是空類就算沒有數據成員,也可以有函數成員的,所以仍然需要實例化,而這個至少會分配1字節空間給空類,就是用于實例化的。(2)字節對齊 (3)靜態成員數據,類似局部靜態數據,存在域全局,作用域局部,在編譯期間就已經初始化,保存在全局數據區中。它的大小不算在類對象里。
  • this指針:使用過程中被編譯器給隱藏起來了,它其實就是個指針,保存調用對象的首地址,指向當前調用者對象本身。對象的成員函數形參處隱式的有這個this,其實是在調用成員函數時,編譯器做了一個小動作:利用寄存器ecx保存了對象的首地址(this),并以寄存器傳參的方式傳遞到成員函數中。這也是在成員函數中能直接訪問成員數據的原因(this->data),也是判斷一個函數不是一般函數而是成員函數的依據。
  • 對象作為函數參數:這個不像數組做參數只傳遞首地址,而是將對象的所有數據成員拷貝一份全部傳遞過去。這個過程其實會調用系統的拷貝構造函數,就是簡單的賦值過程(如果自己寫了這個函數,會替換系統的),所以對于有動態內存分配的類,使用這種傳參,調用系統的拷貝構造函數,會出現一個這樣的錯誤,這種傳參其實是實參與形參處的兩個對象保存著相同的數據,而形參處對象在函數調用結束就會釋放調用對應的析構函數,所以對于實參和參數處的兩個對象都指向的動態空間被釋放了。這時實參處對象的指針還在,但所指內存已經釋放了。所以對于這種需要我們自己定義拷貝構造函數,一般有兩種思路:(1)深拷貝數據,即對于指針數據不僅拷貝指針本身而且指針所指數據也同時拷貝(2)設置引用計數。但是對于對象傳參我們一般使用指針或引用形式,這樣即可以避免上面所說錯誤,同時效率也更高。
  • 對象作為返回值:情況和對象作為函數參數一樣。

總結

以上是生活随笔為你收集整理的C++中类(class)和结构(struct)的区别的全部內容,希望文章能夠幫你解決所遇到的問題。

如果覺得生活随笔網站內容還不錯,歡迎將生活随笔推薦給好友。