最新国产好看的视频,伊人天堂AV在线,国产Aaaaaa视频,蜜臀视频在线观看一区,人妻av色图,密臀久久久精品影片,青青视频免费观看毛片,久草在线观看视,国产三级精品色情在线

C++初識類和對象

 更新時間:2021年10月21日 15:23:55   作者:藍樂  
類是創(chuàng)建對象的模板,一個類可以創(chuàng)建多個對象,每個對象都是類類型的一個變量;創(chuàng)建對象的過程也叫類的實例化。每個對象都是類的一個具體實例(Instance),擁有類的成員變量和成員函數(shù)

一.初步認識面向過程和面向對象

面向過程,關注的是怎么去做,比如在外賣系統(tǒng)中,強調(diào)點餐,做餐,送餐等一系列動作的方法,反映到語言中是函數(shù)方法的實現(xiàn);而面向對象,更關注的是誰去做,比如在外賣系統(tǒng)中,強調(diào)的是商家,買家和送貨員之間的交互,反映到語言中則是對象的實現(xiàn)。

在這里插入圖片描述

C語言是面向過程的,關注的是過程,分析出求解問題的步驟,通過函數(shù)調(diào)用逐步解決問題。

C++是基于面向對象的,關注的是對象,將一件事情拆分成不同的對象,靠對象之間的交互完成。

這里C++由于兼容C語言,因此既是面向過程,又是面向對象的,但是C++更關注的是對象,所以說C++是基于面向對象的。

二.類的引入

在C語言中,結構體只能定義變量,而在C++中,結構體升級為類,既可以定義變量,也可以定義函數(shù):

struct Book
{
	void SetInfo(const char* name, const char* writer, double price)//建立書本信息
	{
		strcpy(_name, name);
		strcpy(_writer, writer);
		_price = price;
	}
	void PrintInfo()//打印書本信息
	{
		cout << _name << endl;
		cout << _writer << endl;
		cout << _price << endl;
	}
	char _name[20];
	char _writer[20];
	double _price;
};
int main()
{
	Book b1;
	Book b2;
	b1.SetInfo("老人與海", "海明威", 12.54);
	b2.SetInfo("駱駝祥子", "老舍", 14.88);
	b1.PrintInfo();
	cout << endl;
	b2.PrintInfo();
	return 0;
}

上面的結構體struct即為一個類,{}則形成了一個類域,{}中的內(nèi)容為結構體Book的成員,既有成員變量,又有成員函數(shù)。在C++中,類通常用class這個關鍵字來表示。那么struct和class二者之間有什么區(qū)別呢?接下來我們就來介紹類。

三.類的定義

class className
{
 // 類體:由成員函數(shù)和成員變量組成
}; // 一定要注意后面的分號

class為定義類的關鍵字,ClassName為類的名字,{}中為類的主體,注意類定義結束時后面分號。

類中的元素稱為類的成員:類中的數(shù)據(jù)稱為類的屬性或者成員變量; 類中的函數(shù)稱為類的方法或者成員函數(shù)。

類的兩種定義方式:

1.定義和聲明全部放在類體中,需要注意的是:

成員函數(shù)被定義在類體中,編譯器會默認將其當作內(nèi)聯(lián)函數(shù),其效用等同于函數(shù)前加上inline關鍵字,若不知道何為內(nèi)聯(lián)函數(shù),可以參考之前文章中關于內(nèi)聯(lián)函數(shù)的介紹。

C++入門

在這里插入圖片描述

2.聲明與定義分離

聲明放在頭文件中,而定義放在源文件中。

在這里插入圖片描述

通常情況下,為了代碼的規(guī)范性,更傾向于采用第二種方法來實現(xiàn)類,并且代碼較短的成員函數(shù)直接定義在類體中,而代碼較長的函數(shù)定義在類體外。

需要注意的是,類中的成員變量均為聲明,它們在實例化之前都未被分配空間,不能稱作為定義。

四.類的訪問限定符及封裝

1.訪問限定符

在之前我們討論到class和struct之間有什么區(qū)別,那么這里我們將會介紹,首先,我們來了解以下類的訪問限定符及封裝。
C++實現(xiàn)封裝的方式:用類將對象的屬性與方法結合在一塊,讓對象更加完善,通過訪問權限選擇性的將其接口提供給外部的用戶使用。

在這里插入圖片描述

訪問限定符的說明:

1.public修飾的成員在類外可以直接被訪問

2.protected和private修飾的成員在類外不能直接被訪問(此處protected和private是類似的)

3.訪問權限作用域從該訪問限定符出現(xiàn)的位置開始直到下一個訪問限定符出現(xiàn)時為止

4.在沒有訪問限定符的情況下,class的默認訪問權限為private,struct為public(因為struct要兼容C)

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

由上面的說明我們就可以知道struct和class這兩個關鍵字之間的區(qū)別在哪里了:實際使用過程中,struct和class定義類時并無區(qū)別,只是在二者均沒有訪問限定符的時候,struct默認的訪問權限為public,而class默認的訪問權限為private。

2.封裝

我們知道面向對象有三大特性:封裝,繼承,多態(tài)。在類和對象階段,我們研究類的封裝特性。

首先,封裝指的是將數(shù)據(jù)和操作數(shù)據(jù)的方法進行有機結合,隱藏對象的屬性和實現(xiàn)細節(jié),僅對外公開接口來和對象進行交互。

其次,從本質上來說,封裝是一種管理:舉個例子,景區(qū)如果不加管理的話,那么景區(qū)的東西很可能會被不守規(guī)章制度的人破壞,這就好比C語言中為被封裝的代碼隨時可能被修改,有時導致出現(xiàn)很大的錯誤;那么為了加強管理,保護景區(qū),就需要設立景點售票口,同時安裝監(jiān)控和保安來保證景區(qū)不被破壞。

類也是如此,對于我們不想被隨意修改的成員變量,我們用private表示其為私有,而為了使用者能夠合理調(diào)用,我們將使用方法封裝成一個個的接口即成員函數(shù)用public表示其為公用,至此我們將成員封裝起來,同時開放一些公有的成員函數(shù)對成員合理的訪問。所以封裝本質是一種管理,使用封裝可以是代碼更加安全。

在這里插入圖片描述

五.類的作用域

類定義了一個新的作用域,類的所有成員都在類的作用域中。在類體外定義成員,需要使用 :: 作用域解析符指明成員屬于哪個類域。

比如,在上面介紹類的第二種實現(xiàn)方式中的代碼,在Book.cpp中定義函數(shù)ShowInfo時就是指定其為類域Book中的成員函數(shù)。

//Book.h
class Book//書
{
public:
	void ShowInfo();//展示書的信息
private:
	char* _name;//書名
	char* _writer;//作者
	double _price;//價格
//Book.cpp
#include "test.h"
void Book::ShowInfo()
{
	cout << _name << " " << _writer << " " << _price << endl;
}
};

六.類的實例化

用類類型創(chuàng)建對象的過程,稱為類的實例化

1.類只是一個模型一樣的東西,限定了類有哪些成員,定義出一個類并沒有分配實際的內(nèi)存空間來存儲它

2.一個類可以實例化出多個對象,實例化出的對象占用實際的物理空間,存儲類成員變量

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

在這里插入圖片描述

在這里插入圖片描述

七.類對象模型

1.計算類對象的大小

類包含了成員變量和成員函數(shù),那么類的大小應該如何計算呢?首先我們來看看下面這個代碼的結果是什么:

class Book
{
public:
	void ShowInfo(){}
private:
	char* _name;
	char* _writer;
	double _price;
};
int main()
{
	cout << sizeof(Book) << endl;
	return 0;
}

在這里插入圖片描述

可以看到,類Book的大小為16,那么這個16是怎么求出來的呢?

2.類對象的存儲方式

我們再來看一個代碼:

class C1//類中既有成員變量,又有成員函數(shù)
{
public:
	void fun();
private:
	int _a;
};
class C2//類中只有成員函數(shù)
{
public:
	void fun();
};
class C3//類中什么都沒有,即空類
{
};
int main()
{
	cout << "C1:" << sizeof(C1) << endl;
	cout << "C2:" << sizeof(C2) << endl;
	cout << "C3:" << sizeof(C3) << endl;
	return 0;
}

它的結果是:

在這里插入圖片描述

可以看到C1的大小為成員變量_a的大小,C2和C3的大小均為1,說明類的大小并不包括成員函數(shù)的大小,實際上如果類實例化時也會給成員函數(shù)開辟一塊空間,那么當一個類創(chuàng)建多個對象時,每個對象中都會保存一份成員函數(shù)的代碼,相同代碼保存多次,浪費空間。

既然成員函數(shù)不在類的大小計算范圍內(nèi),那么為什么空類的大小為1呢?這是因為一個類創(chuàng)建的時候需要開辟一塊空間來占位,因此內(nèi)存需要開辟一個字節(jié),這個字節(jié)的空間是沒有意義的,其不存儲任何有效數(shù)據(jù),但是其標識了空類的存在。

在這里插入圖片描述

結論:一個類的大小,實際就是該類中”成員變量”之和,當然也要進行內(nèi)存對齊,注意空類的大小,空類比較特殊,編譯器給了空類一個字節(jié)來唯一標識這個類。

八.this指針

1.this指針的引出

不知道你是否注意到,在C和C++實現(xiàn)棧的代碼中,二者的函數(shù)參數(shù)有些許不同

在這里插入圖片描述

可以看到,C++的函數(shù)參數(shù)比起C語言實現(xiàn)的函數(shù)都少了一個參數(shù),那么問題來了,在下面代碼中s1和s2都調(diào)用Init函數(shù)時,編譯器是怎么區(qū)別是哪個變量調(diào)用的呢?這就是我們即將要介紹的this指針所起到的作用了。

int main()
{
	cpp::Stack s1;
	cpp::Stack s2;
	s1.Init();
	s2.Init();
	s1.Push(1);
	return 0;
}

實際上,C++編譯器給每個“非靜態(tài)的成員函數(shù)“增加了一個隱藏的指針參數(shù),讓該指針指向當前對象(函數(shù)運行時調(diào)用該函數(shù)的對象),在函數(shù)體中所有成員變量的操作,都是通過該指針去訪問。只不過所有的操作對用戶是透明的,即用戶不需要來傳遞,編譯器自動完成。

在這里插入圖片描述

根據(jù)調(diào)試窗口可以看到this指針就是s1的地址,通過this指針可以訪問s1。

2.this指針的特性

1.this指針的類型:類類型* const,比如上面代碼中的this指針類型為Stack*

2.只能在“成員函數(shù)”的內(nèi)部使用,this作為一個關鍵字不能拿它去當作變量的名字,其使用時可以顯式的使用,比如:

		void Init() 
		{
			this->_a = (int*)malloc(sizeof(int) * 4);
			this->_top = 0;
			this->_capacity = 4;
		}

3.this指針本質上其實是一個成員函數(shù)的形參,是對象調(diào)用成員函數(shù)時,將對象地址作為實參傳遞給this形參。所以對象中不存儲this指針。又因為this指針為形參,而形參和函數(shù)中的局部變量是存儲在函數(shù)棧幀中的,因此this指針可以認為是存儲在棧中的。

4.this指針是成員函數(shù)第一個隱含的指針形參,一般情況由編譯器通過ecx寄存器自動傳遞,不需要用戶傳遞.

在這里插入圖片描述

我們最后再來看一個問題:this指針可以為空嗎?

我們還是通過一個代碼來看:

class A
{
public:
	void Show()
	{
		cout << "Show()" << endl;
	}
	void Print()
	{
		cout << _a << endl;
	}
private:
	int _a;
};
int main()
{
	A* p = nullptr;
	p->Show();
	p->Print();
	return 0;
}

那么p->Show(); p->Print();這兩句代碼能否運行成功呢?

在這里插入圖片描述

在這里插入圖片描述

可以看到第一句代碼運行成功了,而第二句代碼運行崩潰了。

這是因為成員函數(shù)的地址并不存在于對象中,而是存在于公共代碼段;而上面的代碼中調(diào)用函數(shù)時將p傳給了隱含的this指針,并不會去訪問p所指向的空間,就不存在空指針的解引用,因此程序可以并編譯成功。而調(diào)用Show函數(shù)也沒有對this指針解引用,因此程序運行成功了;調(diào)用Print函數(shù)則會對this指針解引用,故程序崩潰了。

結論:對于調(diào)用不會對this指針解引用的函數(shù),this指針可以為空;而對于調(diào)用會對this指針解引用的函數(shù),this指針不能為空。

總結

本篇文章就到這里了,希望能夠給你帶來幫助,也希望您能夠多多關注腳本之家的更多內(nèi)容!

相關文章

  • C++鏈式二叉樹深入分析

    C++鏈式二叉樹深入分析

    二叉樹的鏈式存儲結構是指,用鏈表來表示一棵二叉樹,即用鏈來指示元素的邏輯關系。通常的方法是鏈表中每個結點由三個域組成,數(shù)據(jù)域和左右指針域,左右指針分別用來給出該結點左孩子和右孩子所在的鏈結點的存儲地址
    2022-06-06
  • OpenCV+Qt實現(xiàn)圖像處理操作工具的示例代碼

    OpenCV+Qt實現(xiàn)圖像處理操作工具的示例代碼

    這篇文章主要介紹了利用OpenCV+Qt實現(xiàn)圖像處理操作工具,可以實現(xiàn)雪花屏、高斯模糊、中值濾波、毛玻璃等操作,感興趣的可以了解一下
    2022-08-08
  • Qt QML使用虛擬鍵盤的示例代碼

    Qt QML使用虛擬鍵盤的示例代碼

    這篇文章主要為大家詳細介紹了Qt QML使用虛擬鍵盤的相關知識,文中的示例代碼講解詳細,感興趣的小伙伴可以跟隨小編一起學習一下
    2024-01-01
  • C語言時間函數(shù)之strftime()詳解

    C語言時間函數(shù)之strftime()詳解

    這篇文章主要為大家詳細介紹了C語言時間函數(shù)之strftime(),文中示例代碼介紹的非常詳細,具有一定的參考價值,感興趣的小伙伴們可以參考一下,希望能夠給你帶來幫助
    2022-02-02
  • VS2019中CMake項目如何指定c++語言標準

    VS2019中CMake項目如何指定c++語言標準

    這篇文章主要介紹了VS2019中CMake項目如何指定c++語言標準,需要的朋友可以參考下
    2020-02-02
  • C++深入細致探究二叉搜索樹

    C++深入細致探究二叉搜索樹

    二叉搜索樹是以一棵二叉樹來組織的。每個節(jié)點是一個對象,包含的屬性有l(wèi)eft,right,p和key,其中,left指向該節(jié)點的左孩子,right指向該節(jié)點的右孩子,p指向該節(jié)點的父節(jié)點,key是它的值
    2022-05-05
  • 詳解C語言中的getgrgid()函數(shù)和getgrnam()函數(shù)

    詳解C語言中的getgrgid()函數(shù)和getgrnam()函數(shù)

    這篇文章主要介紹了詳解C語言中的getgrgid()函數(shù)和getgrnam()函數(shù),是C語言入門學習中的基礎知識,需要的朋友可以參考下
    2015-08-08
  • 一篇文章帶你了解C++模板編程詳解

    一篇文章帶你了解C++模板編程詳解

    這篇文章主要介紹了C++的模板,本文給大家介紹的非常詳細,對大家的學習或工作具有一定的參考借鑒價值,需要的朋友可以參考下
    2021-11-11
  • C++快速冪與大數(shù)取模算法示例

    C++快速冪與大數(shù)取模算法示例

    這篇文章主要介紹了C++快速冪算法和大數(shù)取模算法的示例,對C++程序員來說有一定的幫助,有需要的朋友可以參考借鑒,下面來一起看看。
    2016-08-08
  • 使用Qt生成Word和PDF文檔的詳細教程

    使用Qt生成Word和PDF文檔的詳細教程

    Qt 是一個跨平臺的應用程序開發(fā)框架,除了用于創(chuàng)建圖形界面應用程序外,還可以用來生成 Word 和 PDF 文檔,本文將介紹如何使用 Qt 來生成Word和PDF文檔,以及相關的代碼示例,需要的朋友可以參考下
    2023-10-10

最新評論

黑山县| 桃江县| 锡林浩特市| 大化| 三台县| 巴东县| 永新县| 即墨市| 河东区| 娄烦县| 龙游县| 盘山县| 措美县| 黄山市| 故城县| 南投市| 丹寨县| 肥乡县| 托里县| 临澧县| 汕尾市| 宝鸡市| 海城市| 九台市| 寿阳县| 抚顺县| 特克斯县| 长海县| 北票市| 兰溪市| 怀仁县| 南华县| 张家口市| 武邑县| 东乌珠穆沁旗| 保定市| 玉门市| 南阳市| 台前县| 渝北区| 客服|