欧美free性护士vide0shd,老熟女,一区二区三区,久久久久夜夜夜精品国产,久久久久久综合网天天,欧美成人护士h版

首頁綜合 正文
目錄

柚子快報邀請碼778899分享:算法 【C++】類和對象(一)

柚子快報邀請碼778899分享:算法 【C++】類和對象(一)

http://yzkb.51969.com/

文章目錄

一、類的引入二、類的定義語法

三、類的訪問限定符及封裝訪問限定符`public ``private``protected`訪問限定符說明

面試題:question:C++中struct和class的區(qū)別是什么?

四、類的兩種定義方式五、類的作用域六、面向?qū)ο笕筇匦灾唬悍庋b七、類的實(shí)例化八、類對象模型如何計算類對象的大小回顧:結(jié)構(gòu)體內(nèi)存對齊規(guī)則

類對象的存儲方式

一、類的引入

C語言,結(jié)構(gòu)體中只能定義變量。C++中,結(jié)構(gòu)體內(nèi)可以定義變量也可以定義函數(shù)。

?C語言方式實(shí)現(xiàn)的棧,結(jié)構(gòu)體中只能定義變量?,F(xiàn)在以C++的方式實(shí)現(xiàn),結(jié)構(gòu)體中也可以定義函數(shù)。

typedef int DataType;

struct Stack

{

void Init(size_t capacity)

{

_array = (DataType*)malloc(sizeof(DataType) * capacity);

if (nullptr == _array)

{

perror("malloc申請空間失敗");

return;

}

_capacity = capacity;

_size = 0;

}

void Push(const DataType& data)

{

// 擴(kuò)容

_array[_size] = data;

++_size;

}

DataType Top()

{

return _array[_size - 1];

}

void Destroy()

{

if (_array)

{

free(_array);

_array = nullptr;

_capacity = 0;

_size = 0;

}

}

DataType* _array;

size_t _capacity;

size_t _size;

};

int main()

{

//我們可以直接用stack來定義一個結(jié)構(gòu)體s。

//C++中s也可以稱作一個對象。

Stack s;

s.Init(10);

s.Push(1);

s.Push(2);

s.Push(3);

cout << s.Top() << endl;

s.Destroy();

return 0;

}

c語言中,我們通過這種方式來建立一個棧的結(jié)構(gòu),c++將結(jié)構(gòu)體升級為了類,類提供了一種封裝數(shù)據(jù)成員(屬性或變量)和成員函數(shù)上面結(jié)構(gòu)體的定義,在C++中更喜歡用class來代替。

二、類的定義

語法

class className

{

// 類體:由成員函數(shù)和成員變量組成

};

// 一定要注意后面的分號

class為定義類的關(guān)鍵字,ClassName為類的名字,{}中為類的主體,注意類定義結(jié)束時后面分號不能省略。

類體中內(nèi)容稱為類的成員:類中的變量稱為類的屬性或成員變量; 類中的函數(shù)稱為類的方法或者成員函數(shù)。

我們可以簡單定義一個日期類:

class Date

{

int year;

int month;

int day;

};

C++習(xí)慣定義成員變量時在其前面加上符號_,比如以下情況:

class Date

{

void Init(int year, int month, int day)

{

year = year;

}

int year;

int month;

int day;

};

為了防止成員變量和成員函數(shù)的形參混淆,我們可以這樣定義:

class Date

{

void Init(int year, int month, int day)

{

_year = year;

}

int _year;

int _month;

int _day;

};

現(xiàn)在我們來調(diào)用這個函數(shù):

class Date

{

void Init(int year, int month, int day)

{

_year = year;

}

int _year;

int _month;

int _day;

};

int main()

{

Date d1;

d1.Init(2005, 6, 23);

return 0;

}

發(fā)現(xiàn)無法調(diào)用該成員函數(shù)

這就引出我們接下來要講的內(nèi)容,類的訪問限定符

三、類的訪問限定符及封裝

訪問限定符

C++實(shí)現(xiàn)封裝的方式:用類將對象的屬性與方法結(jié)合在一塊,讓對象更加完善,通過訪問權(quán)限選 擇性的將其接口提供給外部的用戶使用。

在 C++ 中,訪問限定符(Access Specifiers)定義了類成員(即變量和函數(shù))的訪問權(quán)限。這些限定符有助于實(shí)現(xiàn)封裝和抽象,是面向?qū)ο缶幊痰暮诵母拍钪?。主要的訪問限定符有三種:public、private 和 protected

public

public成員在任何地方都可以被訪問,類的內(nèi)部、外部都可訪問>使用public限定符可以提高代碼的使用率,但是會降低封裝性,因?yàn)橥獠看a可以直接讀寫公開的數(shù)據(jù)成員

private

private成員只能被類的成員函數(shù)和友元函數(shù)訪問,不能被類的外部訪問。使用 private 限定符是封裝的一種體現(xiàn)。通過限制對成員的直接訪問,你可以保護(hù)類內(nèi)部成員的狀態(tài),避免外部代碼隨意修改,從而維護(hù)對象的完整性

protected

protected 成員可以被其所在類的成員函數(shù)、派生類的成員函數(shù)訪問,但是**不能被類的外部直接訪問**protected 在處理繼承時尤其有用,它允許派生類訪問基類中的成員,同時防止了類的外部直接訪問這些成員

訪問限定符說明

1. 訪問權(quán)限作用域從該訪問限定符出現(xiàn)的位置開始直到下一個訪問限定符出現(xiàn)時為止 2. 如果后面沒有訪問限定符,作用域就到}即類結(jié)束。 3. class的默認(rèn)訪問權(quán)限為private,struct為public(因?yàn)閟truct要兼容C)

注意:訪問限定符只在編譯時有用,當(dāng)數(shù)據(jù)映射到內(nèi)存后,沒有任何訪問限定符上的區(qū)別

面試題

?C++中struct和class的區(qū)別是什么?

答:C++兼容C語言,C++中struct可以當(dāng)作結(jié)構(gòu)體使用,也可以當(dāng)作類去使用。在struct當(dāng)類使用的時候,跟class關(guān)鍵字的區(qū)別是默認(rèn)訪問限定符不同。struct的默認(rèn)訪問限定符是public,class的默認(rèn)訪問限定符是private。在繼承和模板參數(shù)列表位置,struct和class也存在區(qū)別。

四、類的兩種定義方式

聲明和定義全部放在類體中,需注意:成員函數(shù)在類中定義,編譯器可能會將其當(dāng)成內(nèi)聯(lián)函數(shù)處理

class stack

{

public:

int* a;

int size;

int capacity;

void Init(int n=4)

{

a = (int*)malloc(sizeof(int) * n);

if (nullptr == a)

{

perror("malloc申請空間失敗");

return;

}

capacity = n;

size = 0;

}

};

類聲明放在.h文件中,成員函數(shù)定義放在.cpp文件中,注意:成員函數(shù)名前需要加類名::

stack.h文件

class stack

{

public:

int* a;

int size;

int capacity;

void Init();

};

stack.cpp文件,如果我們直接定義該成員函數(shù)則會報錯

報錯原因是:Init()函數(shù)被編譯器當(dāng)作全局函數(shù),Init()函數(shù)操作Stack類的成員變量被編譯器認(rèn)定是訪問未定義的標(biāo)識符。

這說明,如果程序員不加指定,編譯器則無法找到該函數(shù)的出處,根據(jù)搜索規(guī)則,只會先去局部域找然后去全局域搜索這些變量是否被定義過。所以我們要使用訪問限定符::告訴編譯器該函數(shù)操作的成員變量 屬于 哪一個類域。

void stack::Init(int n=4)

{

a = (int*)malloc(sizeof(int) * n);

if (nullptr == a)

{

perror("malloc申請空間失敗");

return;

}

capacity = n;

size = 0;

}

五、類的作用域

由此我們可知,除了全局域、局部域類作用域也會影響編譯器的搜索規(guī)則 ,比如下面兩個類,棧和隊列都有init和push函數(shù):

class stack {

public:

void init(int n);

void push(int x);

};

class queue {

public:

void init(int n);

void push(int x);

};

如果沒有域,則會有沖突。所以,類本身就是一個域。

六、面向?qū)ο笕筇匦灾唬悍庋b

面向?qū)ο蟮娜筇匦裕悍庋b、繼承、多態(tài)

在類和對象階段,主要是研究類的封裝特性,那什么是封裝呢?

封裝(Encapsulation)是面向?qū)ο缶幊蹋∣OP)中的一個核心概念,它指的是將對象的數(shù)據(jù)(屬性)和操作這些數(shù)據(jù)的方法(行為)捆綁在一起的做法。這種機(jī)制可以防止外部代碼隨意訪問對象內(nèi)部的狀態(tài),從而保護(hù)對象的完整性和安全性。封裝的關(guān)鍵在于提供了一個抽象層,使得對象的使用者不需要知道對象內(nèi)部的復(fù)雜邏輯,只需要通過對象提供的接口(公共方法)來與對象進(jìn)行交互

封裝本質(zhì)上是一種管理,讓用戶更方便使用類。比如:對于電腦這樣一個復(fù)雜的設(shè)備,提供給用戶的就只有開關(guān)機(jī)鍵、通過鍵盤輸入,顯示器,USB插孔等,讓用戶和計算機(jī)進(jìn)行交互,完成日常事務(wù)。但實(shí)際上電腦真正工作的卻是CPU、顯卡、內(nèi)存等一些硬件元件

對于計算機(jī)使用者而言,不用關(guān)心內(nèi)部核心部件,比如主板上線路是如何布局的,CPU內(nèi)部是如何設(shè)計的等,用戶只需要知道,怎么開機(jī)、怎么通過鍵盤和鼠標(biāo)與計算機(jī)進(jìn)行交互即可。因此計算機(jī)廠商在出廠時,在外部套上殼子,將內(nèi)部實(shí)現(xiàn)細(xì)節(jié)隱藏起來,僅僅對外提供開關(guān)機(jī)、鼠標(biāo)以及鍵盤插孔等,讓用戶可以與計算機(jī)進(jìn)行交互即可。

七、類的實(shí)例化

class Date

{

public:

void Init(int year, int month, int day)

{

_year = year;

}

int _year;

int _month;

int _day;

};

思考:這里的int _year、int _month、int _day是聲明還是定義?它是聲明

聲明和定義的本質(zhì)區(qū)別是是否開辟一塊空間

class Date

{

public:

void Init(int year, int month, int day)

{

_year = year;

}

int _year;

int _month;

int _day;

};

int main()

{

Date d1;

return 0;

}

Date d1通過實(shí)例化對象,為該對象的所有成員變量開辟空間,整體定義了該對象的所有成員變量。

我們可以通過對象,對該對象的成員變量進(jìn)行訪問。

int main()

{

Date d1;

d1._year++;

//Date::_year++//不能通過類域限定訪問,因?yàn)樗皇锹暶?,沒有開辟一塊空間

return 0;

}

類是對對象進(jìn)行描述的,是一個模型一樣的東西,限定了類有哪些成員,定義出一個類并沒有分配實(shí)際的內(nèi)存空間來存儲它

類實(shí)例化出對象就像現(xiàn)實(shí)中使用建筑設(shè)計圖建造出房子,類就像是設(shè)計圖,只設(shè)計出需要什么東西,但是并沒有實(shí)體的建筑存在,同樣類也只是一個設(shè)計,實(shí)例化出的對象才能實(shí)際存儲數(shù)據(jù),占用物理空間

八、類對象模型

類中既可以有成員變量,又可以有成員函數(shù),那么一個類的對象中包含了什么?如何計算一個類的大???

如何計算類對象的大小

class Date

{

public:

void Init(int year, int month, int day)

{

_year = year;

}

int _year;

int _month;

int _day;

};

int main()

{

cout << sizeof(d1) << endl;

Date d1;

return 0;

}

思考:上面Date類的大小是多少字節(jié)?

先來回顧以下結(jié)構(gòu)體內(nèi)存對齊規(guī)則

回顧:結(jié)構(gòu)體內(nèi)存對齊規(guī)則

第一個成員在與結(jié)構(gòu)體變量偏移量為0的地址處。 其他成員變量要對齊到對齊數(shù)的整數(shù)倍的地址處。 對齊數(shù) = min(編譯器默認(rèn)的對齊數(shù), 該成員大?。?VS中默認(rèn)的值為8 結(jié)構(gòu)體總大小為最大對齊數(shù)(每個成員變量都有一個對齊數(shù))的整數(shù)倍。 如果嵌套了結(jié)構(gòu)體的情況,嵌套的結(jié)構(gòu)體對齊到自己的最大對齊數(shù)的整數(shù)倍處,結(jié)構(gòu)體的整體大小就是所有最大對齊數(shù)(含嵌套結(jié)構(gòu)體的對齊數(shù))的整數(shù)倍。

這里存在成員函數(shù)的情況下,類所占字節(jié)大小依然是12,驗(yàn)證測試如下:

我們嘗試調(diào)用以下不同對象的成員函數(shù)

class Date

{

public:

void Init(int year, int month, int day)

{

_year = year;

}

int _year;

int _month;

int _day;

};

int main()

{

Date d1;

Date d2;

d1.Init(2024, 01, 01);

d2.Init(2025, 01, 01);

return 0;

}

從反匯編代碼中,我們發(fā)現(xiàn)兩個對象分別調(diào)用的成員函數(shù)地址是相同的。

所以類的成員變量、成員函數(shù)到底是如何存儲的呢?

類對象的存儲方式

每個對象中存儲各自的成員變量,成員函數(shù)因?yàn)橐磸?fù)被不同的對象調(diào)用,所以成員函數(shù)存儲在一段公共的區(qū)域。

class A2 {

public:

void f2() {}

};

這個類的大小是多少呢?

在C++中,沒有成員變量的類對象大小占位1字節(jié),不實(shí)際存儲任何數(shù)據(jù),是為了標(biāo)識該對象已經(jīng)被實(shí)例化了。

對于給出的A2類,因?yàn)樗缓幸粋€成員函數(shù),它所占用的內(nèi)存大小應(yīng)該是1字節(jié)

再看下面的代碼示例:將p設(shè)為空指針,p還能調(diào)用函數(shù)嗎?

class fun {

public:

void Print()

{

cout << "被調(diào)用" << endl;

}

};

int main()

{

fun a1;

fun* p1 = &a1;

p1->Print();

fun* p = nullptr;

p->Print();

return 0;

}

測試:

可以調(diào)用的原因:

這里的Print函數(shù)并不在指針指向的空間里面,既不在p1指向的空間里面,也不再p指向的空間里面,p1,p指向的是對象,對象里面沒有函數(shù)的地址,雖然有箭頭,但是并沒有進(jìn)行解引用。

柚子快報邀請碼778899分享:算法 【C++】類和對象(一)

http://yzkb.51969.com/

相關(guān)文章

評論可見,查看隱藏內(nèi)容

本文內(nèi)容根據(jù)網(wǎng)絡(luò)資料整理,出于傳遞更多信息之目的,不代表金鑰匙跨境贊同其觀點(diǎn)和立場。

轉(zhuǎn)載請注明,如有侵權(quán),聯(lián)系刪除。

本文鏈接:http://gantiao.com.cn/post/18989209.html

發(fā)布評論

您暫未設(shè)置收款碼

請在主題配置——文章設(shè)置里上傳

掃描二維碼手機(jī)訪問

文章目錄