我們知道,this指標的預設型別是指向類型別非常常量版本的指標常量。這樣就會帶來乙個問題,我們不能夠把this指標繫結當乙個常量物件上(因為底層const等級不同)。比如下面這個例子。
class
solution;}
;int
main()
此時,我們可以用const關鍵字將getisbn()宣告為常量成員函式,其本質是將this指標宣告為乙個指向常量物件的指標常量。
string getisbn()
const
;// 注意const的位置
此時再呼叫getisbn()就合法,因為this指標的型別是const solution *const,它可以指向型別為const solution的物件。不過,由於this指標是指向常量的指標,所以在const成員函式內不能改變呼叫它的物件的內容。如果非要修改的話,對應的資料成員應該用mutable(可變)修飾。例如:
class
solution
;// 合法
};
此外,建構函式不能夠被宣告成const的。因為當我們建立類的乙個const物件時,直到建構函式完成初始化的過程,物件才真正取得const屬性。因此,建構函式在const物件構造過程中可以對其寫值。
和普通成員類似,我們也可以自定義某種型別在類中的別名,這就是型別成員。它同樣也有訪問限制。
class
solution;}
;int
main()
和普通成員不同的是,型別成員必須先定義後使用。
看下面這個類,其中move和set都是返回值型別是screen&且返回*this的成員函式,這意味著他們的返回值是呼叫物件的引用,從而可以對同一物件s1進行連續操作,所以程式最後輸出的結果是3,4。
class
screen
; screen &
set(
int x,
int y)
;private
:int cor_x =0;
int cor_y =0;
};ostream &
print
(ostream &cout, screen &s)
intmain()
如果將move和set的返回值改為screen型別,結果就會是2,3,因為這相當於在呼叫完set之後建立了乙個新的物件,在對這個新的物件進行move操作,s1本身的值只會被set函式改變一次。
// 將move和set返回值改為screen型別,其他不變。
intmain()
編譯器處理完類中全部宣告後才會處理成員函式的定義。要理解這一點可以看下面這個例子:
typedef
double money;
string bal;
class
account
;private
: money bal;
};
balance的函式體在整個類可見後才會被處理,因此該函式的return語句返回名為bal的成員,而非外城作用域的string物件。
但型別成員要特殊處理,看下面這個例子。
typedef
double money;
string bal;
class
account
;private
:typedef
int money;
money bal;
};
由於內層作用域可以重新定義外層作用域的名字,因此**是合法的。但需要注意的是編譯器只會在首次出現該別名之前尋找別名的定義。比如**中,money balance()的money是外層定義的money,實則double型別,但是money bal的money是類內定義的int型別。所以我們應當避免這種寫法,並且保證型別成員放在類的最前面。
c++11中新增了委託建構函式。乙個委託建構函式使用它所屬類的其他建構函式執行它自己的初始化過程,或者說它把自己的一些(或者全部)職責委託給了其他建構函式。委託建構函式的初始值列表只有乙個,就是其他的建構函式。
舉個例子,下面**輸出construct func1 construct func2。首先data在定義時應該呼叫無引數的建構函式,即輸出func2的函式,隨後由於該建構函式是委託建構函式,它將初始化的一部分委託給輸出func1的建構函式,因而先呼叫sales_data(const string &s, int a),使用初始化列表初始化isbn和cnt,隨後執行函式體輸出construct func1 ,之後控制權回到委託建構函式的函式體,輸出construct func2。
class
sales_data
;sales_data()
:sales_data(""
,0);
// 委託建構函式
private
: string isbn;
int cnt;};
intmain()
如果建構函式只接受乙個實參,則它實際上定義了轉換為此類型別的隱式轉換機制,有時我們把這種建構函式稱為轉換建構函式。
同樣是上面的例子,經過了一點小修改,**中sales_data(const string &s)由於只接受乙個實參,所以它是乙個轉換建構函式。因此sales_data i = s合法,編譯器會用string型別物件s來建立乙個sales_data型別的物件,並把它賦值給i。
但是,兩步轉換是不允許的,比如sales_data i = 「123」 這一句中"123"是const char *型別的,首先他要轉換成string,之後才能由轉換建構函式初始化乙個sales_data物件,這是不允許的。
class
sales_data
;private
: string isbn;
int cnt =0;
};intmain()
此外可以用explicit關鍵字來禁止這種轉換操作。如將上述**中的建構函式改為:
explicit
sales_data
(const string &s)
:isbn
(s);
此時sales_data i = s就是非法的。同時explicit修飾的建構函式只能直接初始化,即sales_data i(s)合法。 C 練習(四)類和物件
構建乙個類book,其中含有兩個私有資料成員qu和price,建立乙個有5個元素的陣列物件,將qu初始化1 5,將price初始化為qu的10倍。顯示每個物件的qu price。標頭檔案book.h includeusing namespace std class book book成員函式.cpp...
《Inside C 》筆記 四 類
類是對資料結構和演算法的封裝。一 類成員 類成員包括以下幾類,作者在後面的章節會詳細講解。字段 用來儲存資料,可用static readonly const來修飾 方法 運算元據的 屬性 用來控制對類內部變數的訪問 常量 索引器 事件和運算子。二 訪問修飾符 public 可被外部的類和派生類訪問 ...
c 物件導向(四) 類的成員
這裡首先介紹類的訪問控制和構造 析構函式,然後介紹屬性,方法 類的成員包括常量 變數 屬性 方法 事件 操作符 建構函式 析構函式等。從訪問控制來看,與類的修飾符類似,類的修飾符用於規定這個類的訪問控制,成員的修飾符就是規定類中成員的訪問控制。修飾符包括 public 允許類外部對這個成員進行訪問 ...