欧美bbbwbbbw肥妇,免费乱码人妻系列日韩,一级黄片

C++類的構(gòu)造與析構(gòu)特點(diǎn)及作用詳解

 更新時(shí)間:2022年10月18日 15:06:21   作者:是星星鴨  
本文章將會可能會涉及到匯編的知識,不過沒有關(guān)系,我會講的盡量通俗易懂;另外本篇文章開始前,建議了解下什么是函數(shù)重載,這個(gè)概念很簡單的--有相同的函數(shù)名,但參數(shù)列表不相同的函數(shù),就是函數(shù)重載

一、類的構(gòu)造函數(shù)

什么是構(gòu)造函數(shù)

和類具有相同名稱,并且沒有返回值類型的函數(shù),就是類的構(gòu)造函數(shù)

概念模糊、直接舉例:

#include <stdio.h>
#include <windows.h>
struct Test
{
    Test()        // 和類具有相同的名、并且沒有返回值
    {
    }
};
int main()
{
    return 0;
}

構(gòu)造函數(shù)的特點(diǎn)

直接先來說特點(diǎn)吧,然后論證:

1、構(gòu)造函數(shù)在定義對象的時(shí)候被調(diào)用

2、構(gòu)造函數(shù)可以進(jìn)行函數(shù)重載,可以有很多個(gè)

3、創(chuàng)建對象時(shí)默認(rèn)調(diào)用的是無參構(gòu)造

證明1:

構(gòu)造函數(shù)在定義對象的時(shí)候被調(diào)用;

論證如下:

#include <stdio.h>
struct Test
{
	Test()
	{
		printf("你調(diào)用了構(gòu)造函數(shù)\n");		// 此處下斷點(diǎn)、如果該函數(shù)被調(diào)用肯定會停下來。
	}
};
int main()
{
	Test te;
	printf("接力\n");
	return 0;
}

我們在Test()構(gòu)造的輸出語句上加斷點(diǎn)、當(dāng)程序調(diào)用Test的printf肯定會停下來,這個(gè)時(shí)候我們轉(zhuǎn)到反匯編,單步步過、直到函數(shù)返回之后,就能知到剛剛是在哪里調(diào)用的構(gòu)造函數(shù)了

vs2010:F7編譯、F5調(diào)試、ALT+8反匯編:

F10一直運(yùn)行到返回:

這里編譯器做了優(yōu)化,可以直接看出來是在Test定義對象的時(shí)候調(diào)用了構(gòu)造。

證明2:

構(gòu)造函數(shù)可以進(jìn)行函數(shù)重載,可以有很多個(gè);

論證如下:

#include <stdio.h>
#include <Windows.h>
struct Test
{
	Test()
	{
		printf("你調(diào)用了構(gòu)造函數(shù)\n");		// 此處下斷點(diǎn)、如果該函數(shù)被調(diào)用肯定會停下來。
	}
	Test(int a)
	{
		printf("重載%d\n",a);
	}
	Test(int a, int b)
	{
		printf("重載%d\n",a+b);
	}
};
int main()
{
	Test te;
	Test te1(1);
	Test te2(1,1);			// 注意、調(diào)用有參的構(gòu)造函數(shù)時(shí),需要傳遞參數(shù)
	system("pause");
	return 0;
}

重載了兩個(gè),注意:調(diào)用有參數(shù)的構(gòu)造時(shí),需要傳遞參數(shù)。

運(yùn)行可以通過:

證明3:

創(chuàng)建對象時(shí)默認(rèn)調(diào)用的是無參構(gòu)造;

論證如下:

#include <stdio.h>
#include <Windows.h>
struct Test
{
	Test(int a)
	{
		printf("重載%d\n",a);
	}
	Test(int a, int b)
	{
		printf("重載%d\n",a+b);
	}
};
int main()
{
	Test te;            // 普通定義對象的方式、不帶參數(shù)
	system("pause");
	return 0;
}

首先我們刪除無參構(gòu)造,看看能否編譯通過:

不可以

然后刪除有參構(gòu)造:

#include <stdio.h>
#include <Windows.h>
struct Test
{
	Test()
	{
		printf("你調(diào)用了構(gòu)造函數(shù)\n");		// 此處下斷點(diǎn)、如果該函數(shù)被調(diào)用肯定會停下來。
	}
};
int main()
{
	Test te;
	system("pause");
	return 0;
}

可以

全部都加上:

#include <stdio.h>
#include <Windows.h>
struct Test
{
	Test()
	{
		printf("你調(diào)用了構(gòu)造函數(shù)\n");		// 此處下斷點(diǎn)、如果該函數(shù)被調(diào)用肯定會停下來。
	}
	Test(int a)
	{
		printf("重載%d\n",a);
	}
	Test(int a, int b)
	{
		printf("重載%d\n",a+b);
	}
};
int main()
{
	Test te;
	system("pause");
	return 0;
}

運(yùn)行結(jié)果:

這已經(jīng)證明了,Test te;平常這樣定義對象的時(shí)候,調(diào)用的是無參構(gòu)造。如果需要調(diào)用有參構(gòu)造,必須傳入?yún)?shù);

這個(gè)特點(diǎn)很簡單、有參函數(shù)肯定要傳參嘛,所以定義對象的時(shí)候肯定要傳入?yún)?shù)??;

但是這里建議無論什么時(shí)候?qū)戭?,最好還是寫上無參構(gòu)造,哪怕什么都不做也盡量寫上,避免不必要的麻煩。

構(gòu)造函數(shù)的作用

一般用于初始化類的成員

如下:

#include <stdio.h>
#include <Windows.h>
struct Test
{
	int x;
	int y;
	int z;
	Test()
	{
	}
	Test(int x,int y,int z)						// 構(gòu)造函數(shù)初始化對象
	{
		this->x = x;
		this->y = y;
		this->z = z;	
	}
};
int main()
{
	Test te;
	Test te1(1,2,3);							// 定義對象并調(diào)用有參構(gòu)造進(jìn)行初始化
	printf("%d %d %d\n",te1.x,te1.y,te1.z);		// 輸出看看是否初始化成功
	system("pause");
	return 0;
}

運(yùn)行如下:

初始化成功。

二、類的析構(gòu)函數(shù)

什么是析構(gòu)函數(shù)

類的構(gòu)造函數(shù)名前加上'~'這個(gè)符號,就是類的析構(gòu)函數(shù)

概念模糊、代碼如下:

#include <stdio.h>
#include <Windows.h>
struct Test
{
	Test()
	{
		printf("你調(diào)用了一次類的構(gòu)造函數(shù)\n");
	}
	~Test()
	{
		printf("你調(diào)用了一次類的析構(gòu)函數(shù)\n");
	}
};
int main()
{
	Test te;
	// system("pause");        // 這里就不要讓程序停下來了,不然析構(gòu)不了
	return 0;
}

~Test(){}就這個(gè)樣子

析構(gòu)函數(shù)的特點(diǎn)

依然直接先來說特點(diǎn),然后論證:

1、析構(gòu)函數(shù)不能重載、不能有參數(shù)

2、析構(gòu)函數(shù)在變量聲明周期結(jié)束時(shí)被調(diào)用

3、析構(gòu)函數(shù)被調(diào)用分兩種情況:堆棧中定義的對象、全局區(qū)中定義的對象

證明1:

析構(gòu)函數(shù)不能重載、不能有參數(shù);

編譯不通過。

既然不能有參數(shù),那重載更不可能了

證明成功。

證明2:

析構(gòu)函數(shù)在變量聲明周期結(jié)束時(shí)被調(diào)用;

局部變量的生命周期是在一個(gè)大括號內(nèi),即一個(gè)所處塊結(jié)束。

所以:

#include <stdio.h>
#include <Windows.h>
struct Test
{
	Test()
	{
		printf("你調(diào)用了一次類的構(gòu)造函數(shù)\n");
	}
	~Test()
	{
		printf("你調(diào)用了一次類的析構(gòu)函數(shù)\n");
	}
};
int main()
{
	{
		Test te;
		printf("te生命周期即將結(jié)束。\n");
	}                                    // 析構(gòu)應(yīng)該在這里被調(diào)用
	printf("te生命周期結(jié)束。\n");
	system("pause");
	return 0;
}

運(yùn)行結(jié)果如下:

斷點(diǎn)

結(jié)果

證明成功。

證明3:

析構(gòu)函數(shù)被調(diào)用分兩種情況:堆棧中定義的對象、全局區(qū)中定義的對象;

已知堆棧中定義的對象(局部變量)在塊語句結(jié)束之后就會被調(diào)用,那么帶有return的main函數(shù)是在返回前調(diào)用析構(gòu),還是返回后呢?

代碼如下:

#include <stdio.h>
#include <Windows.h>
struct Test
{
	Test()
	{
		printf("你調(diào)用了一次類的構(gòu)造函數(shù)\n");
	}
	~Test()
	{
		printf("你調(diào)用了一次類的析構(gòu)函數(shù)\n");			// 斷點(diǎn)--匯編
	}
};
int main()
{
	Test te;
	// system("pause");					// 不要使用pause,不然無法返回
	return 0;
}

斷點(diǎn)-調(diào)試-匯編:

可以看到是在函數(shù)返回前被調(diào)用的。

如果在全局區(qū)定義的對象呢?

這個(gè)問題很難說,像我一樣定義兩個(gè)斷點(diǎn)就行了,如下:

#include <stdio.h>
#include <Windows.h>
struct Test
{
	Test()
	{
		printf("你調(diào)用了一次類的構(gòu)造函數(shù)\n");
	}
	~Test()                                    // 斷點(diǎn)
	{
		printf("你調(diào)用了一次類的析構(gòu)函數(shù)\n");			
	}
};
Test te;
int main()
{
	// system("pause");					// 不要使用pause,不然無法返回
	return 0;                           // 斷點(diǎn)
}

運(yùn)行:

發(fā)現(xiàn)一運(yùn)行就斷在了return,當(dāng)我們發(fā)F10繼續(xù)運(yùn)行的時(shí)候,并沒有直接調(diào)用析構(gòu),而是到了括號那里:

繼續(xù)F10:

通過翻譯,可以得知這就是進(jìn)程結(jié)束時(shí)的一些收尾工作。

繼續(xù)F10:

現(xiàn)在大概可以總結(jié)了,類的對象定義為全局變量時(shí),是在main函數(shù)結(jié)束之后進(jìn)程退出之前,調(diào)用的析構(gòu)函數(shù)。

小結(jié)

當(dāng)類的對象定義為局部變量時(shí)(堆棧),定義這個(gè)對象的塊作用域結(jié)束時(shí)就會調(diào)用該對象的析構(gòu)函數(shù),如果在main函數(shù)這個(gè)塊作用域中定義的對象,那么就是在return之前調(diào)用析構(gòu)。

當(dāng)類的對象定義為全局變量時(shí)(全局區(qū)),會在main函數(shù)return函數(shù)返回之后和進(jìn)程結(jié)束之前,調(diào)用該對象的析構(gòu)函數(shù)。

析構(gòu)函數(shù)的作用

我們知道了析構(gòu)函數(shù)都是在類的對象生命周期結(jié)束時(shí)被調(diào)用,那么就代表下面不會再使用到這個(gè)對象;所以析構(gòu)函數(shù)一般用于一些收尾的工作,以防忘記。

比如當(dāng)你使用了該對象的成員申請了內(nèi)存(malloc、new等)、或者open了一些文件,那么可以在析構(gòu)函數(shù)中free delete 或者close。

例如:

#include <stdio.h>
#include <Windows.h>
struct Test
{
	int x;
	char* name;
	Test()
	{
		name = (char*)malloc(sizeof(char)*20);        // 構(gòu)造時(shí)動(dòng)態(tài)申請
	}
	~Test()
	{
		if(this->name!=0)                             // 析構(gòu)時(shí)判斷是個(gè)否為空,不為空釋放
		{
			free(name);
			name = 0;
		}
	}
};
int main()
{
	Test te;
	return 0;
}

這里我就不運(yùn)行了,大家可以自己測試下。

總結(jié)

構(gòu)造函數(shù)

1、和類具有相同名稱,并且沒有返回值類型的函數(shù),就是類的構(gòu)造函數(shù)

2、構(gòu)造函數(shù)在定義對象的時(shí)候被調(diào)用

3、構(gòu)造函數(shù)可以進(jìn)行函數(shù)重載,可以有很多個(gè)

4、創(chuàng)建對象時(shí)默認(rèn)調(diào)用的是無參構(gòu)造

析構(gòu)函數(shù)

1、類的構(gòu)造函數(shù)名前加上'~'這個(gè)符號,就是類的析構(gòu)函數(shù)

2、析構(gòu)函數(shù)不能重載、不能有參數(shù)

3、析構(gòu)函數(shù)在變量聲明周期結(jié)束時(shí)被調(diào)用

4、析構(gòu)函數(shù)被調(diào)用分兩種情況:堆棧中定義的對象、全局區(qū)中定義的對象

到此這篇關(guān)于C++類的構(gòu)造與析構(gòu)特點(diǎn)及作用詳解的文章就介紹到這了,更多相關(guān)C++類的構(gòu)造與析構(gòu)內(nèi)容請搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關(guān)文章希望大家以后多多支持腳本之家!

相關(guān)文章

  • 詳解c++ atomic原子編程中的Memory Order

    詳解c++ atomic原子編程中的Memory Order

    在多核編程中,我們使用內(nèi)核對象【如:事件對象(Event)、互斥量對象(Mutex,或互斥體對象)、信號量對象(Semaphore)等】來避免多個(gè)線程修改同一個(gè)數(shù)據(jù)時(shí)產(chǎn)生的競爭條件。本文將詳細(xì)介紹c++ atomic原子編程中的Memory Order。
    2021-06-06
  • C語言的數(shù)字游戲算法效率問題探討實(shí)例

    C語言的數(shù)字游戲算法效率問題探討實(shí)例

    這篇文章主要介紹了C語言的數(shù)字游戲算法效率問題探討實(shí)例,需要的朋友可以參考下
    2014-04-04
  • 如何在C++類的外部調(diào)用類的私有方法

    如何在C++類的外部調(diào)用類的私有方法

    這篇文章主要介紹了如何在C++類的外部調(diào)用類的私有方法,文章圍繞主題展開詳細(xì)的內(nèi)容介紹,具有一定的參考價(jià)值,需要的朋友可以參考一下
    2022-09-09
  • C語言中時(shí)間的基本用法小結(jié)

    C語言中時(shí)間的基本用法小結(jié)

    處理時(shí)間是編程中經(jīng)常遇到的問題,C語言中提供了一些時(shí)間處理函數(shù),在此記錄下一些基本的用法。下面這篇文章主要給大家介紹了C語言中關(guān)于時(shí)間的基本用法的相關(guān)資料,需要的朋友可以參考借鑒,感興趣的朋友們來一起看看吧。
    2017-01-01
  • 淺析在C/C++中如何寫調(diào)試宏

    淺析在C/C++中如何寫調(diào)試宏

    這篇文章主要為大家詳細(xì)介紹了在C/C++中如何寫調(diào)試宏的相關(guān)知識,文中的示例代碼講解詳細(xì),具有一定的借鑒價(jià)值,有需要的小伙伴可以參考一下
    2024-05-05
  • C++中讀寫txt文件并分離字符的方法

    C++中讀寫txt文件并分離字符的方法

    今天小編就為大家分享一篇C++中讀寫txt文件并分離字符的方法,具有很好的參考價(jià)值,希望對大家有所幫助。一起跟隨小編過來看看吧
    2018-07-07
  • c++素?cái)?shù)篩選法

    c++素?cái)?shù)篩選法

    本文講的是篩選法的C++實(shí)現(xiàn), 篩選法又稱篩法,是求不超過自然數(shù)N(N&gt;1)的所有質(zhì)數(shù)的一種方法。據(jù)說是古希臘的埃拉托斯特尼(Eratosthenes,約公元前274~194年)發(fā)明的,又稱埃拉托斯特尼篩子。
    2017-05-05
  • C語言各類操作符全面講解

    C語言各類操作符全面講解

    C?語言提供了豐富的操作符,有:算術(shù)操作符,移位操作符,位操作符,賦值操作符,單目操作符,關(guān)系操作符,邏輯操作符,條件操作符等。接下了讓我們詳細(xì)了解掌握它
    2022-05-05
  • C語言中數(shù)組排序淺析

    C語言中數(shù)組排序淺析

    這篇文章主要為大家介紹了C語言算法練習(xí)中數(shù)組元素排序的四種類型,文中的示例代碼講解詳細(xì),對我們學(xué)習(xí)C語言有一定幫助,需要的可以參考一下
    2022-12-12
  • C++函數(shù)模板學(xué)習(xí)示例教程指南

    C++函數(shù)模板學(xué)習(xí)示例教程指南

    這篇文章主要為大家介紹了C++函數(shù)模板學(xué)習(xí)示例教程指南,有需要的朋友可以借鑒參考下,希望能夠有所幫助,祝大家多多進(jìn)步,早日升職加薪
    2023-04-04

最新評論