c++中有六大預設成員函式:構建物件
初始化型別轉換(單參才能轉換)
沒有返回值,並且不能指定返回值型別
函式名與類名相同
建立物件是由編譯器自動呼叫(在物件生命週期內只會呼叫一次)
可以過載
如果沒有顯示定義,編譯器會預設合成乙個預設的建構函式(在有必要的情況下:如類成員變數中有類物件,且該類物件有自己的建構函式)
也可以放在類外定義(像類成員函式一樣)
預設建構函式一般只能有乙個:1.無參的; 2.全預設的。
不能宣告為const
關於第7點可能有點模糊,舉個例子:
8.詳解class sales_item ;class date
date(int a = 1, int b = 2)
private:
int _year;
int _month;
int day;
};int main()
const 建構函式是不必要的。建立類型別的 const 物件時,執行乙個普通
建構函式來初始化該 const 物件。建構函式的工作是初始化物件。不管物件是
否為 const,都用乙個建構函式來初始化化該物件
如果類中包含://date類建構函式
date(int year = 2016, int month = 1, int day = 1)
: _year(year) //實際初始化順序按類中成員變數排列順序進行初始化,與這裡的顯示順序無關
, _month(_year) //隨意這個順序最好也按類中成員變數排列順序來
, _day(_month)
非靜態const資料成員(即沒有static修飾的)
引用沒有預設建構函式的類成員變數
則需要在初始化列表進行初始化。
對這裡的第3點再來舉個例子:
如下依舊做了優化:
通常,除非有明顯的理由想要定義隱式轉換,否則,單形參建構函式應該為 explicit。將建構函式設定為explicit 可以避免錯誤,並且當轉換有用時,使用者可以顯式地構造物件。
類通常應定義乙個預設建構函式
在某些情況下,預設建構函式是由編譯器隱式應用的。如果類沒有預設建構函式,則該類就不能用在這些環境中。為了例示需要預設建構函式的情況,假定有乙個 nodefault 類,它沒有定義自己的預設建構函式,卻有乙個接受乙個string 實參的建構函式。因為該類定義了乙個建構函式,因此編譯器將不合成預設建構函式。nodefault 沒有預設建構函式,意味著:
1. 具有 nodefault 成員的每個類的每個建構函式,必須通過傳遞乙個初始的 string 值給 nodefault 建構函式來顯式地初始化 nodefault 成員。
2. 編譯器將不會為具有 nodefault 型別成員的類合成預設建構函式。如果這樣的類希望提供預設建構函式,就必須顯式地定義,並且預設建構函式必須顯式地初始化其 nodefault 成員。
3. nodefault 型別不能用作動態分配陣列的元素型別。
4. nodefault 型別的靜態分配陣列必須為每個元素提供乙個顯式的初始化式。
5. 如果有乙個儲存 nodefault 物件的容器,例如 vector,就不能使用接受容器大小而沒有同時提供乙個元素初始化式的建構函式。實際上,如果定義了其他建構函式,則提供乙個預設建構函式幾乎總是對的。通常,在預設建構函式中給成員提供的初始值應該指出該物件是「空」的。
一種特殊的建構函式
只有單個形參:本類類物件的引用(一般為常引用,因為實參的值不需要被改變)
若沒有顯示定義,則合成乙個預設的拷貝建構函式
用物件構建物件時呼叫(需要產生乙份拷貝)(用臨時物件構建物件時編譯器會做優化,不呼叫拷貝建構函式,而是呼叫建構函式)
例:
date(const date &d)
2.詳解:引數為什麼一定要為引用?
如果引數為date d,那麼實參傳遞給形參的時候,將呼叫拷貝建構函式(要生成乙份引數的拷貝);呼叫拷貝建構函式就又要傳參,傳參又要呼叫拷貝建構函式,如此遞迴下去,棧終將溢位!
4.詳解:關注建構函式中最後的例子。
涉及到淺拷貝與深拷貝:如果類成員變數中有指標,那麼預設的拷貝建構函式將只賦值指標的值,而不複製指標所指向記憶體空間的內容(淺拷貝),所以實際上兩個物件中的這個變數都指向同一塊記憶體,對其中乙個指標指向的記憶體修改,另乙個也會改變,不安全。同理,賦值運算子最好也過載。
在物件銷毀時,由編譯器自動呼叫
~類名(){}
沒返回值
沒引數(不能過載)
若沒有顯示定義,則編譯器預設合成乙個
析構函式體內並不是刪除物件,而是做一些清理工作
例: ~date(){}
物件在棧上分配,棧後進先出。所以同一作用域的物件,先構造的後析構.
引數至少有乙個類型別(或自定義型別)
運算子過載後不保證順序,尤其是&&,||
== 和 !=一般成對過載
過載後置++,--多乙個int型引數,用以區分前置++,--,呼叫時由編譯器自動傳參
當內建操作符和型別上的操作存在邏輯對應關係時,操作符過載最有用。使用過載操作符而不是創造命名操作,可以令程式更自然、更直觀,而濫用操作符過載使得我們的類難以理解。
為類設計過載操作符的時候,必須選擇是將操作符設定為類成員還是普通非成員函式。在某些情況下,程式設計師沒有選擇,操作符必須是成員;在另一些情況下,有些經驗原則可指導我們做出決定。下面是一些指導原則,有助於決定將操作符設定為類成員還是普通非成員函式:
1.賦值(=)、下標()、呼叫(())和成員訪問箭頭(->)等操作符必須定義為成員,將這些操作符定義為非成員函式將在編譯時標記為錯誤。
2.像賦值一樣,復合賦值操作符通常應定義為類的成員,與賦值不同的是,不一定非得這樣做,如果定義非成員復合賦值操作符,不會出現編譯錯誤。
3.改變物件狀態或與給定型別緊密聯絡的其他一些操作符,如自增、自減和解引用,通常就定義為類成員。
4.對稱的操作符,如算術操作符、相等操作符、關係操作符和位操作符,最好定義為普通非成員函式。
date.cpp:
c 類的預設成員函式
類的組成包括資料成員與成員函式。在類中一共有有六個預設成員函式,建構函式 拷貝建構函式 析構函式 賦值操作符過載 取位址操作符過載 const修飾的取位址操作符過載 利用乙個例項 日期類 進行舉例 先是定義乙個日期類 class date 這就是乙個簡單的類定義。下面依次介紹各個預設成員函式 一.建...
C 類的預設成員函式
class test 這些函式只有在需要的時候才會產生,空類占用 個位元組。類為了保護資料成員,其所有資料成員都預設是私有的 private 這也就意味著程式只能通過類裡面的函式提供介面來訪問資料成員。例如,下面程式用日期類建立了乙個物件,並進行初始化 class date int main 為了解...
C 預設成員函式
概念 object oriented programming,縮寫 oop 是一種程式設計范型,同時也是一種程式開發的方法。物件指的是類的例項,將物件作為程式的基本單元,將程式和資料封裝其中,以提高軟體的重用性 靈活性和擴充套件性。c 不是純物件導向語言,而是基於物件導向的語言 ps 因為它包含c的...