c 學習筆記 類

2021-06-26 04:34:31 字數 3767 閱讀 3255

c++學習筆記--類

refer:

c++ primer

在c++中,用類來定義自己的抽象資料結構。

在乙個原始檔中,乙個類只能被定義一次(宣告可以多次),如果在多個檔案中定義乙個類,那麼每個檔案定義必須完全相同。

可以宣告乙個類而不定義它。這個宣告被稱為向前宣告,是乙個不完全型別(已知其為乙個型別,但不知道包含哪些成員)。

在建立類的物件之前必須完整地定義這個類(編譯器需要知道這個類物件的大小以為其分配相應的記憶體)。同樣,在使用指標、引用訪問類的成員前,必須定義類。

由於類定義之後可以接乙個物件列表,因此定義必須以分號結束。

const類物件只能呼叫const成員函式;非const類物件可以呼叫const與非const成員函式。

當成員函式需要返回物件本身時,需要使用this指標,例:

class test;

test& test::func()

return *this;//注意,這時*this,不是this

test test_obj;

test_obj.func().func().func();

這時可以使用test類物件,將呼叫成員函式連線成乙個單獨的表示式。

類資料成員與類成員函式中的區域性變數衝突且需要使用類資料成員時,使用this指標。

mutable關鍵字:

const類物件只能訪問const類成員函式,const類物件及const類成員函式原意就是不允許修改類的任何資料成員,但是如果需要修改其中一部分資料成員,而不允許修改其他的資料成員,那麼可以再想修改的資料成員前加上關鍵字mutable,這樣就醫修改const類物件的mutable資料成員,在const成員函式中也可以修改mutable資料成員。

類作用域:

在類的作用域之外,只能通過類物件、類物件指標來訪問類的成員。

而定義型別的成員,使用作用域操作符::來訪問,例:

class test //這是初始化

test() //這是賦值

int num;

double rate;

test::

建構函式不能是const,也是沒必要的,因為可以使用非const建構函式生成const類物件,以此來初始化const物件。//todo 這種轉化有沒有產生乙個臨時變數,是不是屬於自動轉化?

普通內建型別的資料成員不進行隱式初始化,所以對這些成員進行初始化還是賦值在效能上等價的。

內建型別資料成員如果定義在全域性作用域,那麼會進行初始化。

類型別的資料成員會進行隱式初始化,使用該類型別的預設建構函式。

但是對於任何const或引用資料成員及沒有預設建構函式的類型別資料成員必須使用初始化。因為const及引用無法賦值只能初始化。

資料成員的初始化順序是其宣告的次序。

類如果定義了乙個建構函式,那麼編譯器則不會生成預設建構函式。預設建構函式是沒有形參的建構函式。

在乙個類中如果定義了乙個具有全部是預設實參的建構函式,那麼就不能再定義過載建構函式,因為在會發生過載的歧義。

乙個類a沒有預設建構函式(或者具有預設實參的建構函式)意味著:

1.每個該類物件初始化必須傳入實參;

2.具有該類a物件作為資料成員的類b,如果b想要提供預設建構函式,那麼b必須在預設建構函式中顯示地初始化a物件;

3.a類物件不能作為動態分配陣列的元素型別,例:int num = 10; a array[num];語句非法

4.a類的靜態陣列必須為每個元素提供乙個顯示初始化,例: a array[10];語句非法

5.儲存a類物件的容器不能使用接受容器大小而不提供元素初始化的建構函式,例:std::vectorvec_a(100);這個語句是非法的。

隱式型別轉換:

具有乙個形參的建構函式定義了從形參型別到該類型別的隱式轉換,例:

class test()

test(int);

void func(test);

test tst(10);

tst.func(99);//在test類中func函式需要乙個test型別物件,但是現在傳入乙個int物件,編譯仍然可以過,這是因為編譯器使用建構函式將int轉換為test。

可以使用關鍵字explicit來抑制此種隱式轉換。explicit關鍵字只能用於類內部的建構函式宣告上,類外部定義不能重複它。當建構函式被宣告為explicit時,編譯器將不是呀他作為轉換操作符(todoy我理解是不將此建構函式作用於類內部預設的操作符過載oprator=)。

可以顯式地使用建構函式來生成轉換,例:

class test()

test(int);

void func(test);

test tst(10);

tst.func(test(99));//

顯式使用建構函式只是中止了隱式地使用建構函式,任何建構函式都可以用來顯式建立臨時物件。

友元:友元機制允許乙個類將對其非公有成員的訪問權授予指定的函式或類。友元宣告只能在類定義的內部以關鍵字friend開始。友元宣告可以出現在類的任何地方。

類必須將過載函式集中每乙個希望設為友元的函式都宣告為友元。

無法定義const型別的引用,引用無法被賦值只能初始化,引用是物件指向記憶體的別名但是無法解位址*。

static類成員的優點:

1.static成員名字在類的作用域內,因此避免了與其他類的成員或全域性物件名字衝突;

2.可以實施封裝,static類成員可以使私有成員,而全域性物件不可以;

3.**清晰,容易看出static成員是與特定類關聯的。

static類資料成員是儲存在bss中而不是在類物件內。static類資料成員只能在類定義外部定義,且定義時不能新增static關鍵字,不能通過類建構函式初始化,而是在定時時初始化。如果初始化式是乙個常量表示式,那麼const static資料成員可以:1在類內部初宣告且始化,內外部定義且不能初始化;2在內部宣告且不初始化,類外部必須定義初始化;3在類內部宣告且定義它。例:

class test()

static int num;//不能在此處初始化

static const int rate0 = 99;//因為99是是常量表示式,且在類內部宣告初始化

static const int rate1 = 99;//因為99是是常量表示式,且在類內部宣告初始化

static const int rate2 = 99;//因為99是是常量表示式,且在類內部宣告定義初始化,類外部沒有定義

private:

int func();

int test::num = func();//只能在內定義外部處定義且不能標識為static,且static成員在類作用域內,因此可以訪問該類的私有成員

const int test::rate0;//不能初始化

const int test::rate1 = 99;//必須初始化

要記得定義乙個變數時不一定需要初始化。

變數的定義(definition):用於為變數分配儲存空間,還可以為變數指定初始值(也可以不初始化)。在乙個程式中,變數有且僅有乙個定義。

變數的宣告(declaration):用於向程式表明變數的型別和名字。

定義也是宣告:當定義變數時我們宣告了它的型別和名字。可以通過使用extern關鍵字宣告變數名而不定義它。

對於int a;來說,它既是定義又是宣告;對於exter

n int a;來說,它是宣告不是定義。一般為了敘述方便,

把建立儲存空間的宣告稱定義,而不把建立儲存空間的宣告稱為宣告。

static成員函式沒有this指標。static成員函式除了可以通過類物件、物件指標、物件引用來呼叫外,還可以使用【類名::方法】來呼叫。static成員函式不能被宣告為const型別、virtual型別。

c 學習筆記 類

物件的定義 類名 物件名 如stock joe 物件使用成員函式 物件名.成員函式名 如joe.show 呼叫成員函式時,成員函式使用的是呼叫它的物件的資料成員。類所建立的每個物件都有自己的儲存空間,儲存其內部變數和類成員。但每乙個物件都共享類的同一組方法。類的建構函式和析構函式 建構函式是為了在構...

C 類 學習筆記

類的深入刨析 i 建構函式 析構函式 拷貝建構函式 何時呼叫建構函式和析構函式 預設的逐個成員賦值 類的深入刨析 ii 運算子過載字串和陣列物件 繼承多型性 成員訪問說明符public private和protected類的作用域和類成員的訪問 物件的名稱或者物件的引用要結合圓點成員選擇運算子 來訪...

c 學習筆記 類繼承

現在有乙個記錄身份id的類 ifndef head h define head h include include using namespace std class idcard endif 實現部分 include head.h idcard idcard const string n,cons...