构造函数与析构函数是类的重要组成部分,他们在类中担任着至关重要的工作。够战术常用来完成对象的生成时的初始化工作,而析构函数则常用于在对象销毁时释放对象中的所申请的资源。
当对象生成时,编译器会自动产生调用其类的构造函数的代码,在编码构成中可以分为类中的数据尘烟赋予的初始值,当对象销毁时,编译器同样也会产生调用其析构函数的代码。
构造函数与析构函数都是类中特殊的函数,构造函数可以重载,而析构函数只能有一个,而且析构函数是一个无参析构函数,他们均没有返值,调用构造函数后,返回值为对象的首地址, 也就是我们熟知的this指针。
我们知道,某些情况下,编译器会提供默认的构造函数和析构函数,但是,并不是任何的情况下编译器都提供。问题来了,构造函数出现的时机是在什么时间呢?
构造函数出现的时机
对象在生成时会自动调用构造函数,只要找到了定义对象的地址地方就找到了构造函数的调用时机啦。看似简单,实际情况却相反哦。不同作用域的对象的生命周期也不同,如局部对象,全局对象,静态对象等的生命周期各不相同。而对象作为参数与返回值时,构造函数的出现时机又会不同。
将对象进行分类:不同类型的对象的构造函数被调用的时机会发生变化,但是都会遵循C++语法:定义的同时调用构造函数。那么,只要知道对象的生命周期,便可以推算出构造函数的调用时机。下面先根据生命周期将对象分类,主要分为下面几类:
A,局部对象
B,堆对象
C,参数对象
D,返回对象
E,全局对象
F,静态对象
我们先看看局部对象。
局部对象的构造函数出现的时机比较容易被识别。当对象产生时,便有可能引发构造函数的调用,编译器隐藏了构造函数的调用过程,使编码者无法看到被调用的细节。我们看看下面的分析代码,了解下局部对象的构造函数调用的过程。
class CNumber { public: CNumber() { m_number = 1; } private: int m_number; }; ///----主函数 int main() { CNumber number; system("pause"); ///-暂停显示数据 return 0; }在看看对应的构造函数和主函数的汇编代码。
汇编函数的汇编代码:
class CNumber { public: ///---构造函数 CNumber() 00123620 push ebp 00123621 mov ebp,esp 00123623 sub esp,0CCh 00123629 push ebx 0012362A push esi 0012362B push edi 0012362C push ecx 0012362D lea edi,[ebp-0CCh] 00123633 mov ecx,33h 00123638 mov eax,0CCCCCCCCh 0012363D rep stos dword ptr es:[edi] 0012363F pop ecx 00123640 mov dword ptr [this],ecx { ///--变量成员赋值 m_number = 1; 00123643 mov eax,dword ptr [this] 00123646 mov dword ptr [eax],1 } 0012364C mov eax,dword ptr [this] 0012364F pop edi 00123650 pop esi 00123651 pop ebx 00123652 mov esp,ebp 00123654 pop ebp 00123655 ret再看看主函数 对应的汇编代码:
00123EE0 push ebp 00123EE1 mov ebp,esp 00123EE3 sub esp,0D0h 00123EE9 push ebx 00123EEA push esi 00123EEB push edi 00123EEC lea edi,[ebp-0D0h] 00123EF2 mov ecx,34h 00123EF7 mov eax,0CCCCCCCCh 00123EFC rep stos dword ptr es:[edi] 00123EFE mov eax,dword ptr ds:[0012F004h] 00123F03 xor eax,ebp 00123F05 mov dword ptr [ebp-4],eax CNumber number; 00123F08 lea ecx,[number] 00123F0B call CNumber::CNumber (01214A6h) system("pause"); ///-暂停显示数据 00123F10 mov esi,esp 00123F12 push 12CC70h 00123F17 call dword ptr ds:[1301E8h] 00123F1D add esp,4 00123F20 cmp esi,esp 00123F22 call __RTC_CheckEsp (012132Fh) return 0; 00123F27 xor eax,eax
◆该成员函数是这个对象在作用于内调用的第一个成员函数,根据this指针即可以区分每个对象
◆这个函数返回this指针
构造函数必然满足以上两个条件,否则这个函数就不是构造函数。
续...................................................