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

C++類的構造與析構特點及作用詳解

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

一、類的構造函數

什么是構造函數

和類具有相同名稱,并且沒有返回值類型的函數,就是類的構造函數

概念模糊、直接舉例:

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

構造函數的特點

直接先來說特點吧,然后論證:

1、構造函數在定義對象的時候被調用

2、構造函數可以進行函數重載,可以有很多個

3、創(chuàng)建對象時默認調用的是無參構造

證明1:

構造函數在定義對象的時候被調用;

論證如下:

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

我們在Test()構造的輸出語句上加斷點、當程序調用Test的printf肯定會停下來,這個時候我們轉到反匯編,單步步過、直到函數返回之后,就能知到剛剛是在哪里調用的構造函數了

vs2010:F7編譯、F5調試、ALT+8反匯編:

F10一直運行到返回:

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

證明2:

構造函數可以進行函數重載,可以有很多個;

論證如下:

#include <stdio.h>
#include <Windows.h>
struct Test
{
	Test()
	{
		printf("你調用了構造函數\n");		// 此處下斷點、如果該函數被調用肯定會停下來。
	}
	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);			// 注意、調用有參的構造函數時,需要傳遞參數
	system("pause");
	return 0;
}

重載了兩個,注意:調用有參數的構造時,需要傳遞參數。

運行可以通過:

證明3:

創(chuàng)建對象時默認調用的是無參構造;

論證如下:

#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;            // 普通定義對象的方式、不帶參數
	system("pause");
	return 0;
}

首先我們刪除無參構造,看看能否編譯通過:

不可以

然后刪除有參構造:

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

可以

全部都加上:

#include <stdio.h>
#include <Windows.h>
struct Test
{
	Test()
	{
		printf("你調用了構造函數\n");		// 此處下斷點、如果該函數被調用肯定會停下來。
	}
	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;
}

運行結果:

這已經證明了,Test te;平常這樣定義對象的時候,調用的是無參構造。如果需要調用有參構造,必須傳入參數;

這個特點很簡單、有參函數肯定要傳參嘛,所以定義對象的時候肯定要傳入參數?。?/p>

但是這里建議無論什么時候寫類,最好還是寫上無參構造,哪怕什么都不做也盡量寫上,避免不必要的麻煩。

構造函數的作用

一般用于初始化類的成員

如下:

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

運行如下:

初始化成功。

二、類的析構函數

什么是析構函數

類的構造函數名前加上'~'這個符號,就是類的析構函數

概念模糊、代碼如下:

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

~Test(){}就這個樣子

析構函數的特點

依然直接先來說特點,然后論證:

1、析構函數不能重載、不能有參數

2、析構函數在變量聲明周期結束時被調用

3、析構函數被調用分兩種情況:堆棧中定義的對象、全局區(qū)中定義的對象

證明1:

析構函數不能重載、不能有參數;

編譯不通過。

既然不能有參數,那重載更不可能了

證明成功。

證明2:

析構函數在變量聲明周期結束時被調用;

局部變量的生命周期是在一個大括號內,即一個所處塊結束。

所以:

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

運行結果如下:

斷點

結果

證明成功。

證明3:

析構函數被調用分兩種情況:堆棧中定義的對象、全局區(qū)中定義的對象;

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

代碼如下:

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

斷點-調試-匯編:

可以看到是在函數返回前被調用的。

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

這個問題很難說,像我一樣定義兩個斷點就行了,如下:

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

運行:

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

繼續(xù)F10:

通過翻譯,可以得知這就是進程結束時的一些收尾工作。

繼續(xù)F10:

現(xiàn)在大概可以總結了,類的對象定義為全局變量時,是在main函數結束之后進程退出之前,調用的析構函數。

小結

當類的對象定義為局部變量時(堆棧),定義這個對象的塊作用域結束時就會調用該對象的析構函數,如果在main函數這個塊作用域中定義的對象,那么就是在return之前調用析構。

當類的對象定義為全局變量時(全局區(qū)),會在main函數return函數返回之后和進程結束之前,調用該對象的析構函數。

析構函數的作用

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

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

例如:

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

這里我就不運行了,大家可以自己測試下。

總結

構造函數

1、和類具有相同名稱,并且沒有返回值類型的函數,就是類的構造函數

2、構造函數在定義對象的時候被調用

3、構造函數可以進行函數重載,可以有很多個

4、創(chuàng)建對象時默認調用的是無參構造

析構函數

1、類的構造函數名前加上'~'這個符號,就是類的析構函數

2、析構函數不能重載、不能有參數

3、析構函數在變量聲明周期結束時被調用

4、析構函數被調用分兩種情況:堆棧中定義的對象、全局區(qū)中定義的對象

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

相關文章

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

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

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

    C語言的數字游戲算法效率問題探討實例

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

    如何在C++類的外部調用類的私有方法

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

    C語言中時間的基本用法小結

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

    淺析在C/C++中如何寫調試宏

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

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

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

    c++素數篩選法

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

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

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

    C語言中數組排序淺析

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

    C++函數模板學習示例教程指南

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

最新評論