類的簡述

c++的語言特性支持oop和gp編程。
oop是指面向對象編程。gp是指泛型編程。

c++的核心特徵就是class
一個好的class應滿足以下條件:正確、 易維護、高效、優雅、易使用、易讀、易理解

實體類、抽象類、類繼承是class的三大基礎模塊

實體類
如果她的行爲看起來像一個內置類型,就可以稱爲實體類
eg:vector string 看起來像一個內置類型,除此之外她的行爲更豐富

容器:一個對象,可以存儲一系列元素

構造和析構函數是一種優雅的技術,也是c++基本的資源管理的技術
資源在構造中初始化,在析構中釋放,這就是典型的Resource Acquisition Is Initialization(RAII)

構造函數的初始化列表 {}

抽象類
相比實體類,抽象類屏蔽了類的實現
virtual:may be redefined later in a class derived from this one
純虛函數表示:子類必須實現這個函數
如果一個類帶有純虛函數,那麼這個類稱爲抽象類
一個類爲其他不同類型的類提供接口,這種成爲多態
抽象類不需要構造函數,畢竟她沒有數據需要初始化
專業術語:子類(subclass)、父類(superclass)
派生類可以稱爲基類的一個繼承成員,所以在繼承體系中,常稱基類和派生類
在派生類中實現基類的成員,可稱爲override

在多態的引用中有一張表稱爲虛函數表vtbl(virtual function table)
每一個含有虛函數的類都有自己的這麼一張表,用來定位自己的虛函數,相比不含有虛函數的類,在空間上只是多了一個vtbl的指針

類繼承
由推導(eg, : public)而創建的一個類的集合
虛析構函數:如果基類指針指向派生類對象,使用虛析構函數可以保證析構時調用派生類的析構函數。當類中有虛函數時,纔將析構函數弄成虛析構。

虛析構函數調用機制,只是保證了可以正確調用到派生類的析構。

override:基類的虛函數,在派生類中重寫
有個比較好的方式就是在派生類中 針對基類的虛函數添加override關鍵字,來顯示指出這個函數是override的。這一點在google的開源庫中很常見。

類繼承有啥好處
第一:接口繼承。任何需要基類的地方,派生類都可以用上。這些個基類常常是抽象類。
第二:現實繼承。基類可以提供一些已實現的函數和數據,這樣派生類都可以用到。這些個基類常常會提供數據成員和構造函數。

具體類表現的像是一個內置類型(本地變量、訪問是直接用就行)。類在繼承體系中就有所不同(一般用new申請,用指針或是引用來訪問)

當一個基類指針指向派生類對象時,這時如果需要調用派生來的某些特別的接口(基類沒有的),可以用dynamic_cast來進行轉換。

dynamic_cast如果轉換失敗,返回nullptr

防止資源泄漏
在極少數情況下我們使用了new,而忘了delete,這時會導致資源泄漏
新標準推薦我們使用unique_ptr

當一個類是一個資源句柄(通過指針訪問類裏的對象),這時賦值操作會違背類的不變式(eg:如果複製一個容器,當一個容器的大小改變時,另一個容器的不變式就出錯了)。所以類最好包含兩個成員:拷貝構造和複製賦值。
A(const A& a);
A& operator=(const A& a);

新標準向前發展出了移動構造和移動賦值
在具體瞭解這個知識點之前,我們先了解一下新標準中的新玩意 && 右值引用
在c++11中引入的概念rvalue reference,右值引用,寫法類似於T&&。
右值引用分3種:無名、有名、轉發。
無名和有名在這而的意思可以參考namespace的無名有名。
無名和有名主要是解決移動語義的問題,轉發主要是解決完美轉發的問題

關於右值引用的東西上一篇文章中已經描述了一部分,現在就不說了

一個類中比較重要的幾個操作:
構造、析構、拷貝、移動。這幾個並不是邏輯上獨立的。eg:拷貝構造、移動賦值。
新標準爲了提高編程效率,對於上面借個特殊的操作,添加了”=default”和”=delete”;前一個表示,嗨哥們,不用寫函數體了,讓編譯器自動加一個高效的實現;後一個表示,嗨哥們,這個實現已經被disable了

如果構造函數只有單個參數,那麼這時的寫法就很自由:
V a(123);
V b = 456;
第二種情況看起來就不那麼優雅,推薦使用explicit來修改構造函數

資源管理

額外話題(新標準向前走了一大步:提供了線程庫)
資源包括很多方面:內存、系統線程、文件句柄、socket、鎖等,這些資源被我們使用的時候大多使用指針句柄來引用,新標準推薦我們使用stl中的類型來代替,eg:unique_ptr、thread、vector、string、fstream等,這樣可以減少資源泄漏,這些都是c++的gc(垃圾回收機制,不需要我們考慮資源釋放),使用這些可以使代碼更加優雅更加健壯。

Garbage collection:gc,全局內存管理機制

泄漏一般出現在長時間運行的程序中。如果一個程序佔用了太多資源,這種情況和泄漏一樣,好不到哪去。
在c++中raii(Resource Acquisition Is Initialization)非常普遍,這些都可以解決泄漏或是佔用資源太多的情況。

在類繼承中默認的拷貝和移動是不可取的,eg:基類有一個指針,但是不知道派生類中有哪些成員,所以就無法拷貝,這時就需要=delete

class A{
public:
    A(const A&) = delete;
    A& operator=(const A&) = delete;
    A(A&&) = delete;
    A& operator=(A&&) = delete; 
};

=delete 也有人稱爲“抑制操作”

基類一般很少有拷貝和移動 ,如果非要這麼做 ,就是用virtual吧

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章