c 入門學習 類

2021-03-31 15:17:59 字數 4126 閱讀 4871

1. 類

1.1 類的一些概念

(1) c++中類與結構的區別是:類定義中成員預設情況是private,而結構中是public的;

(2) c++中的結構也可以有成員函式的;

(3) ::前面可以沒有類名,表示全域性資料或者全域性函式,在類中呼叫非成員函式要使用::號;::前可以有兩種型別的名稱,一種是命名空間的名稱,一種是類的名稱;

(4) 類法的呼叫與普通的成員函式呼叫不一樣,類名::類方法

(5) 類的構造及析構函式沒有返回型別,它們是在物件建立及失效時自動執行的;

(6) 類是乙個抽象概念,它是乙個不佔記憶體的實體,因此在類的宣告中不能出現賦值及物件的初始化等,如int i = 3, string s(「test」)等,這些初賦值或者初始化的工作可以放在建構函式(因為它是構造物件的所在),也可以放在類的初始化列表中;

(7) 類物件的建立是分配空間、構造結構及初始化的三位一體。

1.2 物件的建立方法

如果定義了乙個類,類名為tdate,那麼它有以下幾中可能的tdate物件建立方法:

(1) tdate d;呼叫tdate的預設建構函式;

(2) tdate d();呼叫tdate的無引數建構函式;

(3) tdate d(引數);

(4) tdate d = tdate(引數);新建立乙個無名物件,再把該物件賦值給d,呼叫了tdate的構造及賦值函式。對類中的成員物件的初始化很有用;

(5) tdate *d = new tdate(引數),這時訪問物件成員應用->,如d->getdate(),這種宣告後最好用if(d == null)來判斷記憶體分配是否成功;

(6) tdate *d = (tdate *) malloc(sizeof(tdate));這種宣告要手工呼叫它的建構函式及析構函式,並且也要用if(d == null)判斷記憶體是否分配成功;

(7) tdate m(d):用已有的指定物件建立新的指定物件,呼叫的是tdate的拷貝函式;

(8) tdate d = 「2004-03-02」:如果使用這種方法,tdate必須有乙個char *型別的構造成函式,即tdate(char * mdate),這表明可以使用字串建立tdate物件,這裡使用了建構函式的型別轉化功能。或者有乙個可以由char*構造的型別做為引數,如tdate(string date),char *可以轉化成string,所以也可以轉化為tdate。最常見的建構函式型別轉化就是string類的使用,如string s = 「hello」;

(9) auto_ptrd(new tdate(引數)):建立乙個可以自動記憶體管理的物件,d是乙個指標,它指向建立的物件;使用auto_ptr類模板需要包含memory標頭檔案。這種定義方法的記憶體空間的刪除需要呼叫類模板auto_ptr的成員方法。

(10) auto_ptrd1(d):根據d建立乙個自動記憶體管理的物件,並且d中的資源的所有權轉給了d1,即如果d和d1共同擁有乙個堆的記憶體空間,即使要用delete刪除也只需要delete d1。

(11) 還有一種建立方法,就是在先預分配物件的記憶體,然後再在該記憶體中真正的建立物件,這種方法需要加入new標頭檔案,如:

class foo

foo(int i=1)

private:

int _val;

};char *buf = new char[sizeof(foo)*2]; //預分配記憶體

int main()

程式執行後,輸出的值為2:3。使用這種方法可以重複利用指定的記憶體空間,不需要反覆的動態分配記憶體,已分配的記憶體到真正不用時再刪除。

全域性物件在主函式開始執行前首先被建立,區域性物件在程式執行遇到它們的物件定義時才被建立。

從堆上分配物件陣列,只能呼叫預設的建構函式,不能呼叫其它任何建構函式,如果類沒有預設的建構函式,那麼就不能分配動態的物件陣列。如:

class s

private:

string m_name;

};int main()

上述**使用s *p = new s[10],企圖建立物件陣列,但是因為類s中沒有預設的建構函式,所以建立不成功。

(12) 物件另一種建立方法是:

class test2

};test2 k = ;

這種物件初始化的方法類似於對陣列的初始化,直接對k,k1這兩個資料成員賦值,不過這種初始化方法有很大限制性,如不能自定義建構函式等。

(13) 物件陣列的建立:

class test

int m_i;

int m_j;

};test t[2] = ;

1.3 類的初始化列表

類的初始化列表位於建構函式的引數列表後,函式體前,這表明在物件結構還沒有建立(物件結構的建立由建構函式完成)。因此初始化列表有已以下幾個特殊的作用:

(1) 初始化常量,因為常量是不能賦值,它必須在宣告的同時就給它賦值,而類的宣告中又不能有賦值語句,因為賦值語句會帶來一系列的記憶體分配。因此常必須在物件結構還沒有建立前初始化,所以需要放在初始化列表中進行;

(2) 引用變數的初始化,原因與第一條相同;

(3) 物件成員的初始化,如:

class studentid

private:

int value;

};class student

private:

studentid m_id;

const string m_name;

const string &m_name1;

};當然對於成員物件的初始化也可以在建構函式中進行,如:

class student

private:

studentid m_id;

const string m_name;

const string &m_name1;

};在初始化列表中不允許出現d=10這樣的形式。

1.4 構造及順序

c++規定,每個類必須有乙個建構函式,如果在定義類時沒有定義建構函式,那麼c++會提供乙個預設的建構函式,它是乙個無引數的建構函式,不做初始化工作,只僅負責建立(構造)物件。只要類定義了乙個建構函式(無論它是否帶函式),那麼c++就不會再提供這個建構函式,這時最自定義乙個無引數的建構函式,否則classname obj這樣的定義方法就不能再用了,而要使用classname obj(….)這樣的定義方法。但是如果使用classname obj();這樣的語句,在宣告時不會出錯,因為它定義了乙個obj這樣的函式,它的返回型別是classname。

區域性和靜態物件,以宣告的順序構造,不是以執行的順序,而且所有變數和物件都在函式開始執行時,統一定義的,如:

int main()

以上程式有在有的編譯器中是通不過的,如果通過它的執行結果為5,0。與之類似,類的成員資料以在類中也是以它們的宣告順序構造的,如:

class test

friend ostream &operator<<(ostream &o,const screen &s);

private:

int m_width;

int m_height;

};ostream &operator<<(ostream &o,const screen &s)

;int main()

輸出的值是97。

1.9 位域

位域的功能非常強大,它可以將資料型別定義到bit位,當然如果只定義了乙個變數,並且它的長度為1bit,實現上它佔的記憶體空間還是1個位元組(當然這根據它的定義了)。因為在類中如果可能的話,它相鄰定義的位成員會被放在同乙個位元組的相鄰位,不過個人認為還是定義為structure的好。所以定義位變數時,一般是需要定義多個位變數,並且使它們的總長度為byte的整數倍。對位成員的訪問與其它資料成員的訪問是一樣的。以下是位域使用的示例:

class bit

;union test

;int main()

在使用位域的時候與union一起使用比較常用,這樣對位時候的賦值就比較方便了,不用乙個乙個的為每個位成員賦值,只要給union成員(一般長度是所有位成員長度的和)賦值即可。

使用位域的強大功能可以方便的實現不同編碼之間的轉化,如binary轉化為bcd,ebcdic等。在以後的文章中我可能會用它來實現bit、byte、bcd、ebcd、bitset、byteset、bcdset等類。

還有,因為位成員是以位為單位的所以它沒有詳細的位址,不能使用指標來訪問。它也不能是類的靜態成員。

1.10 區域性類

區域性類就是在函式體內定義的類。

C 學習入門(六) 靜態類和密封類

1.3 靜態方法 1.4 靜態成員關鍵 1.5 靜態方法與例項方法區別 1.4 靜態類 2.密封類 靜態成員又叫類成員,是指在成員型別或返回值型別前使用static關鍵字修飾的變數或方法。在c 中,能夠宣告為靜態成員的類成員包含靜態成員 靜態屬性 靜態方法 建構函式 運算子 事件等類成員。常量和索引...

C 學習入門(三) 抽象類

2.實現的案例 3.異常處理 抽象類往往用來表徵對問題領域進行分析 設計中得出的抽象概念,是對一系列看上去不同,但是本質上相同的具體概念的抽象。在c 中,抽象類可以包含 抽象方法 抽象屬性 具體方法和具體屬性。訪問修飾符 abstract class 類名 抽象類的定義類似於普通類,只不過在訪問修飾...

C 學習(1)入門與類初識

1.函式過載 什麼是過載 同一作用域內,允許函式名相同,引數列表不同的函式同時出現。乙個函式名對應多種函式實現 注 c 支援,c語言不支援 底層原理 c語言與c 編譯器對函式進行編譯的處理機制不同,c語言編譯器只是簡單的對函式名進行修飾 列入修飾名僅僅是對函式名加個 然後通過修飾名進行鏈結。而c 編...