程式設計師成長之旅 類和物件中篇

2021-09-26 22:59:22 字數 4782 閱讀 5585

析構函式

拷貝建構函式

賦值運算子過載

const成員

取位址及const取位址運算子過載

如果乙個類中什麼都沒有,我們都知道它是空類,但是空類是不是什麼事情都不做,答案當然是否定的,它會生成6個預設函式。

概念

建構函式是乙個特殊的成員函式,名字與類名相同,建立類型別物件時由編譯器自動呼叫,保證每個資料成員都有 乙個合適的初始值,並且在物件的生命週期內只呼叫一次。

特性
建構函式是特殊的成員函式,需要注意的是,建構函式的雖然名稱叫構造,但是需要注意的是建構函式的主要任務並不是開空間建立物件,而是初始化物件。

1.函式名與類名相同

2.無返回值

3.函式可以過載

4.物件例項化時編譯器自動呼叫

class date

// 2.帶參建構函式

date

(int year,

int month,

int day)

private:

int _year;

int _month;

int _day;};

void

testdate()

5.如果沒有顯示定義建構函式,也可以例項化物件成功,因為這裡呼叫的是無參的預設建構函式。

class date

*/private:

int _year;

int _month;

int _day;};

void

test()

6.無參的建構函式和全預設的建構函式都稱為預設建構函式,並且預設建構函式只能有乙個。注意:無參建構函式、全預設建構函式、我們沒寫編譯器預設生成的建構函式,都可以認為是預設成員函式。

class date

date

(int year =

1900

,int month =1,

int day =1)

private:

int _year;

int _month;

int _day;};

// 以下測試函式能通過編譯嗎?

void

test()

//當然是不能通過的,因為這裡定義了多個預設建構函式

7.c++把型別分成內建型別(基本型別)和自定義型別。內建型別就是語法已經定義好的型別:如int/char…,自定義型別就是我們使用class/struct/union自己定義的型別,看看下面的程式,就會發現編譯器生成預設的建構函式會對自定型別成員_t呼叫的它的預設成員函式。

class time

private:

int _hour;

int _minute;

int _second;};

class date

;int

main()

8.要注意命名規格

class date

private:

int year;};

// 所以我們一般都建議這樣

class date

private:

int _year;};

// 或者這樣。

class date

private:

int m_year;

};

概念
前面通過建構函式的學習,我們知道乙個物件時怎麼來的,那乙個物件又是怎麼沒呢的?

析構函式:與建構函式功能相反,析構函式不是完成物件的銷毀,區域性物件銷毀工作是由編譯器完成的。而物件在銷毀時會自動呼叫析構函式,完成一些資源清理的工作。

特性

1.前面要加上~

2.無引數無返回值

3.物件生命週期結束時,編譯器會自動呼叫析構函式

4.乙個類有且只有乙個析構函式,若為顯示定義,編譯器會預設生成析構函式

5. 關於編譯器自動生成的析構函式,是否會完成一些事情呢?下面的程式我們會看到,編譯器生成的預設析構函式,對會自定型別成員呼叫它的析構函式。

class string

~string()

private:

char

* _str;};

class person

;int

main()

概念
只有單個形參,該形參是對本類型別物件的引用(一般常用const修飾),在用已存在的類型別物件建立新物件時由編譯器自動呼叫。

特性

1.拷貝建構函式是建構函式的乙個過載形式

2.拷貝建構函式的引數只有乙個,且必須使用引用傳參,使用傳值會引發無限遞迴呼叫

class date

void

print()

date

(const date& d)

//必須引用傳參 const 是防止拷貝構造的同時修改了原內容

private:

int _year;

int _month;

int _day;};

intmain()

3.若未顯示定義,系統生成預設的拷貝建構函式。 預設的拷貝建構函式物件按記憶體儲存按位元組序完成拷貝,這種拷貝我們叫做淺拷貝,或者值拷貝。

class date

private:

int _year;

int _month;

int _day;};

intmain()

4.那麼編譯器生成的預設拷貝建構函式已經可以完成位元組序的值拷貝了,我們還需要自己實現嗎?當然像日期類這樣的類是沒必要的。那麼下面的類呢?驗證一下試試?

class string

~string()

private:

char

* _str;};

intmain()

運算子過載
c++為了增強**的可讀性引入了運算子過載,運算子過載是具有特殊函式名的函式,也具有其返回值型別,函式名字以及引數列表,其返回值型別與引數列表與普通的函式類似。

函式名字為:關鍵字operator後面接需要過載的運算子符號。

函式原型:返回值型別 operator操作符(引數列表)

注意:

賦值運算子過載

class date

date

(const date& d)

date& operator=

(const date& d)

}private:

int _year;

int _month;

int _day;

};

引數型別

返回值檢測是否自己給自己賦值

返回*this

乙個類如果沒有顯式定義賦值運算子過載,編譯器也會生成乙個,完成物件按位元組序的值拷貝。

class date

private:

int _year;

int _month;

int _day;};

intmain()

那麼編譯器生成的預設賦值過載函式已經可以完成位元組序的值拷貝了,我們還需要自己實現嗎?當然像日期類這樣的類是沒必要的。那麼下面的類呢?驗證一下試試?

class string

~string()

private:

char

* _str;};

intmain()

const修飾類的成員函式

const具體意思

1.const物件不可以呼叫非const成員函式

2.不能修改當前物件的成員變數

3.const 修飾this指標//date* const this(this 指標的模式)

void display()const//限制this指標指向的物件

4.mutable 關鍵字

mutable int _day 這樣在const裡面就是可以修改的

5.非const物件可以呼叫const物件

6.const成員函式內可以呼叫其它的非const成員函式嗎?不可以

7.非const成員函式內可以呼叫其它的const成員函式

8.const date* operator&()const

這兩個預設成員函式一般不用重新定義 ,編譯器一般都會預設生成

class date

const date* operator&()

const

private :

int _year ;

// 年

int _month ;

// 月

int _day ;

// 日

};

這兩個運算子一般不需要過載,使用編譯器生成的預設取位址的過載即可,只有特殊情況,才需要過載,比如想讓別人獲取到指定的內容!

程式設計師成長之旅 順序表

執行效果 靜態順序表是只適用於我們已經了解到需要存多少資料,而一般我們都是用動態順序表,下面我給大家展示一下我所實現的動態順序表的 seqlist.h define crt secure no warnings 1 pragma once include include include includ...

程式設計師成長之旅 設計迴圈佇列

設計你的迴圈佇列實現。迴圈佇列是一種線性資料結構,其操作表現基於 fifo 先進先出 原則並且隊尾被連線在隊首之後以形成乙個迴圈。它也被稱為 環形緩衝器 迴圈佇列的乙個好處是我們可以利用這個佇列之前用過的空間。在乙個普通佇列裡,一旦乙個佇列滿了,我們就不能插入下乙個元素,即使在佇列前面仍有空間。但是...

程式設計師成長之旅 二分查詢

最終 溢位問題在迴圈體中,一般計算中間值middle時所用的是 middle left right 2 但是這種情況容易溢位,因為一旦left right超過所在型別的範圍的話,就會出現錯誤,為了不出現這種問題,我們引入了 middle left right left 2 邊界問題 迴圈體外的初始化...