C 類和物件

2021-09-25 15:52:29 字數 4031 閱讀 5361

this指標

類的預設成員函式

const成員

類似於現實中具體某個事物,和事物抽象的類別(比如我的ipad和平板電腦,西安和城市),相應的,在計算機的世界中也有物件的概念。用描述乙個功能和模組,並用例項化的方式創造乙個物件,讓他在程式中發揮作用。

類的概念有點像c語言中的結構體,但是比起結構體,類有更多豐富的屬性和功能。比如在類中除了可以定義成員變數,還可以定義成員函式,以及訪問限定符等等。

定義乙個類:

class

classname

//成員函式

int stu;

char name[

1024];

//成員變數};

//不要忘記分號

類的訪問限定符可以通過定義訪問許可權的方式讓一些變數隱藏起來,只向外提供一些介面給使用者使用。

class

student

protected

:char ***[

1024];

//被protected修飾的成員只能在類的內部訪問

private

:int stu;

//被private修飾的成員只能在類的內部訪問

};

class的預設訪問許可權為private,而struct的預設訪問許可權是public(因為struct要相容c語言)。

類的作用域:類定義了乙個新的作用域,類的所有成員都在類的作用域中。在類外定義成員時需要使用::作用限定符。再類內的成員變數相當於對於成員函式來說相當於是乙個「全域性變數」。

類是一些物件的抽象描述,就類似於數學模型和真實的物體。例項化物件就是按照數學模型「造出」真實物體的過程。和現實按照數學模型可以建造多個實體一樣,乙個類可以例項化多個物件

例項化物件的過程和定義變數類似:

student a;

//這樣就是使用了上面定義的student例項化了乙個物件a

類中既有成員函式又有成員變數時,如何計算類的大小呢?

答案是:類的大小時就成員變數之和,同時和結構體一樣,類在計算大小時也要考慮記憶體對齊的問題。

物件的儲存方式為:不同物件的成員變數單獨儲存,而成員函式則同用一塊**段空間。這樣節省了函式重複儲存浪費的空間,而每個物件的資料又不會互相影響。

特殊的情況:空類的大小為1位元組(vs中)。

上面我們講到了物件的儲存方式是成員變數單獨儲存而成員函式公用**段。

class

number

show()

private

:int ret;};

intmain()

但是問題來了,上面這串**,set函式和show函式的**是物件n1和n2公用的,那麼它們是怎麼知道它們需要操作的是哪個物件裡的ret變數呢?

c++中使用了this指標來解決這個問題。c++編譯器給每個函式增加了乙個隱藏的指標,讓他們指向當前執行時呼叫它們的物件,再函式體中所有成員函式的操作都是通過該指標去訪問的,這個操作由編譯器自動完成。不需要使用者操作。(但使用者可以操作this指標)

前面我們知道了有空類,它們裡面什麼都沒有定義。但空類中真的什麼都沒有嗎?其實並不是,類在建立時,都會預設生成一些成員函式。這類成員函式有6個,稱作預設成員函式。

就像建立變數一樣,物件在建立時,我們也想將一些變數初始化,為它們賦值。但是對於類來說,它的成員變數是不可以直接初始化的。

class

time

;//這樣初始化物件中的變數是不行的

因為類是抽象的型別,並不是乙個實體。沒有佔據記憶體空間,不能儲存資料。 想要初始化變數,必須將所有變數都宣告為公用,並按照下面的方法進行初始化。

class

time

;time t1 =

;

這樣雖然解決到了初始化的問題,但顯然已經違背了我們保護變數的初衷。所以我們需要另尋出路,而這條出路就是建構函式

建構函式的名字必須和類名相同,以便編譯器識別它。它不具有任何型別,不具有返回值。功能由使用者自定,沒有定義時系統會自動生成乙個無參的建構函式。

class

time

time()

//乙個沒有引數的建構函式

time

(int h,

int m,

int s)

//乙個帶引數的建構函式

private

: in.t hour;

int min;

int sec;};

intmain()

有建構函式進行初始化,就有析構函式完成對物件的資源的釋放。

class

sqlist

~sqlist()

}private

:int

* _p;

size_t _size;

size_t _cap;

};

就像變數一樣,有時候我們希望用乙個變數的初始化另乙個變數。我們也希望能建立乙個和原有物件一模一樣的新物件。這時我們就可以用到另乙個預設成員函式:拷貝建構函式。

拷貝建構函式只有乙個形參,改形參是對本類物件的引用(一般用const修飾),在用已有物件建立新物件時,編譯器自動呼叫。

class

date

date

(const date& d)

private

:int _year;

int _month;

int _day;

};

其實拷貝建構函式相當於建構函式的乙個過載。它只有乙個引數,而且必須傳引用,如果傳值,會引發無限遞迴呼叫。

沒有顯式定義時,系統會生成預設的拷貝建構函式。預設的拷貝建構函式會按原物件的記憶體儲存按位元組序完成拷貝,這種拷貝叫做淺拷貝,或者值拷貝。如果記憶體中含有指標變數,這種拷貝的方式就會讓指標指向同一塊記憶體空間。這樣在釋放這段空間時,就會被釋放兩次,導致**崩潰。

我們想要比較字串是否相等, 我們會本能的想到使用"==", 但是字串比較是需要使用strcmp函式來進行比較的. 為了能夠讓**更加好看一些, 我們可以用運算子過載的方式讓運算子在**中有另外的含義.

//在全域性過載 == 運算子

bool operator==

(const date& d1,

const date& d2)

賦值運算子過載需要注意五點:

引數型別

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

返回 *this

乙個類如果沒有顯式定義賦值運算子過載, 編譯器會自動生成乙個, 用來完成按位元組序的值拷貝. (淺拷貝)

編輯器預設的複製運算子過載函式可以完成位元組序的拷貝工作, 這樣的拷貝叫做淺拷貝, 當類中有malloc等函式, 在堆上申請了記憶體空間時, 會在釋放空間的時候崩潰.

const不僅可以修飾變數, 在類中, 它還可以修飾成員函式.

const修飾函式時, 實際上修飾的是該成員函式隱含的this指標, 被const修飾的成員函式不能對類的任何成員進行修改.

類中的成員函式可以通過增加const實現過載.

class di

void

func1()

const

}void

test()

這段**, 物件d1會呼叫非const的成員函式, 物件d2會呼叫const成員函式. 如果只有乙個const / 非const成員函式, 那麼const 和非const物件都會呼叫同意個成員函式. 另外:

C 類和物件 類和物件

c 中物件的型別稱為類,類代表了某一批物件的共性和特徵,類是物件的抽象,而物件是類的具體例項,類是抽象的,不占用記憶體,而物件是具體的,占用 儲存空間,這點很重要,讀者需要牢記。類是使用者自己指定的型別,如果程式中要用到類型別,必須自己根據需要進行宣告,或者使用別人已設計好的類,c 標準本身並不提供...

C 物件和類

1,特殊的類 字串string include include using namespace std int main 類似於標準庫函式,我們不需要記住每種 類 的全部操作,只需要在使用過程中記住一些常用的操作就可以了。如果有需要的話,可以求助於相關書籍或網路 2,當我們對string進行種種操作...

C (類和物件)

類成員函式 類的成員函式指標那些把定義和原型寫在類定義內部的函式,就想類定義中的其他變數一樣。類訪問修飾符 類成員可以定義為public,private或protected。預設情況下是定義為private。建構函式 類的建構函式是一種特殊的函式,在建立乙個新物件是呼叫。析構函式 類的析構函式也是一...