本篇內(nèi)容介紹了“c++對象構(gòu)造順序和析構(gòu)函數(shù)舉例分析”的有關(guān)知識,在實際案例的操作過程中,不少人都會遇到這樣的困境,接下來就讓小編帶領(lǐng)大家學(xué)習(xí)一下如何處理這些情況吧!希望大家仔細(xì)閱讀,能夠?qū)W有所成!
創(chuàng)新互聯(lián)專注于呼圖壁企業(yè)網(wǎng)站建設(shè),響應(yīng)式網(wǎng)站,成都商城網(wǎng)站開發(fā)。呼圖壁網(wǎng)站建設(shè)公司,為呼圖壁等地區(qū)提供建站服務(wù)。全流程按需網(wǎng)站制作,專業(yè)設(shè)計,全程項目跟蹤,創(chuàng)新互聯(lián)專業(yè)和態(tài)度為您提供的服務(wù)
一、對象的構(gòu)造順序:
1、對于局部對象:
當(dāng)程序執(zhí)行流到達(dá)對象的定義語句時進行構(gòu)造。下面還是用代碼來解析這句話:
#include
class Test
{
private:
int mi;
public:
Test(int i)
{
mi=i;
printf("Test(int i) is %d\n",mi);
}
Test(const Test& obj)
{
mi=obj.mi;
printf("Test(const Test&) obj is %d\n",mi);
}
};
int main()
{
int i = 0 ;
Test a1 =i;//Test(int i):0
while(i<3)
{
Test a2 = ++i;//Test(int i):1,2,3
}
if(i<4)
{
Test a = a1; //Test(const Test& obj is :0
}
else
{
Test a(100);
}
return 0;
}
輸出結(jié)果:
Test(int i) is 0
Test(int i) is 1
Test(int i) is 2
Test(int i) is 3
Test(const Test& obj) is 0
這里我們可以看出當(dāng)程序流執(zhí)行到相應(yīng)的構(gòu)造對象的那條執(zhí)行語句時,就會調(diào)用構(gòu)造函數(shù)(或者拷貝構(gòu)造函數(shù))。goto語句想必大家不陌生,但是都害怕這玩意,下面我們加入goto語句看看會產(chǎn)生什么現(xiàn)象:
#include
class Test{
private:
int mi;
public:
Test(int i)
{
mi=i;
printf("Test(int i) is %d\n",mi);
}
Test(const Test& obj)
{
mi=obj.mi;
printf("Test(const Test& obj is %d\n",mi);
}
};
int main()
{
int i = 0; //Test(int i) :0
Test a1 = i;
while( i <3)
{
Test a2 = ++i; //Test(int i) :1,2,3
}
goto end;
if(i <4)
{
Test a = a1;//Test(const Test&) obj is :0
}
else
{
Test a(100);
}
end:
return 0;
}
輸出結(jié)果:
Test(int i) is 0
Test(int i) is 1
Test(int i) is 2
Test(int i) is 3
從結(jié)果我們可以看出從if那條語句就被跳過了,沒有執(zhí)行到,這里這樣寫的目的是為了引出,當(dāng)你使用goto語句,把對象給屏蔽了,后面你不能使用這個對象了,不然程序會出現(xiàn)大問題:
#include
class Test{
private:
int mi;
public:
Test(int i)
{
mi=i;
printf("Test(int i) is %d\n",mi);
}
Test(const Test& obj)
{
mi=obj.mi;
printf("Test(const Test& obj is %d\n",mi);
}
int getMi()
{
return mi;
}
};
int main()
{
int i = 0; //Test(int i) :0
Test a1 = i;
while( i <3)
{
Test a2 = ++i; //Test(int i) :1,2,3
}
goto end;
Test a(100);
end:
printf("a.mi is %d\n",a.getMi());
return 0;
}
輸出結(jié)果:
tt.cpp: In function ‘int main()’:
tt.cpp:32:1: error: jump to label ‘end’ [-fpermissive]
end:
^
tt.cpp:30:6: error: from here [-fpermissive]
goto end;
^
tt.cpp:31:12: error: crosses initialization of ‘Test a’
Test a(100);
^
這里就是上面所說了的,對象被goto語句給屏蔽了,后面就不能使用這個對象來進行操作了。
2、對于堆對象:
當(dāng)程序執(zhí)行流到達(dá)new語句時創(chuàng)建對象
使用new創(chuàng)建對象將自動觸發(fā)構(gòu)造函數(shù)的調(diào)用
代碼演示:
#include
class Test
{
private:
int mi;
public:
Test(int i)
{
mi = i;
printf("Test(int i): %d\n", mi);
}
Test(const Test& obj)
{
mi = obj.mi;
printf("Test(const Test& obj): %d\n", mi);
}
int getMi()
{
return mi;
}
};
int main()
{
int i = 0;
Test* a1 = new Test(i); // Test(int i): 0
while( ++i < 10 )
if( i % 2 )
new Test(i); // Test(int i): 1, 3, 5, 7, 9
if( i < 4 )
new Test(*a1);
else
new Test(100); // Test(int i): 100
return 0;
}
輸出結(jié)果:
Test(int i): 0
Test(int i): 1
Test(int i): 3
Test(int i): 5
Test(int i): 7
Test(int i): 9
Test(int i): 100
3、對于全局對象:
對象的構(gòu)造順序是不確定的
不同的編譯器使用不同的規(guī)則來確定構(gòu)造順序。
同樣還是來看代碼示例,這里我創(chuàng)建了幾個文件:tes1.cpp test2.cpp test3.cpp test4.cpp test.h;他們的內(nèi)容如下:
test1.cpp:
#include "test.h"
Test t4("t4");
int main()
{
Test t5("t5");
}
test2.cpp:
#include "test.h"
Test t1("t1");
test3.cpp:
#include "test.h"
Test t2("t2");
test4.cpp:
#include "test.h"
Test t3("t3");
test.h:
#ifndef _TEST_H_
#define _TEST_H_
#include
class Test
{
public:
Test(const char* s)
{
printf("%s\n", s);
}
};
#endif
最后輸出結(jié)果:
root@txp-virtual-machine:/home/txp# g++ test1.cpp test2.cpp test3.cpp test4.cpp -o put
root@txp-virtual-machine:/home/txp# ./put
t4
t1
t2
t3
t5
4、小結(jié):
局部對象的構(gòu)造順序依賴程序的執(zhí)行流
堆對象的構(gòu)造順序依賴于new的使用順序
全局對象的構(gòu)造順序是不確定的
二、析構(gòu)函數(shù):
1、c++的類中可以定義一個特殊的清理函數(shù),叫做析構(gòu)函數(shù),這個函數(shù)的功能與構(gòu)造函數(shù)相反,顧名思義就是銷毀的意思了。
2、定義:~ClassName()
析構(gòu)函數(shù)沒有參數(shù)也沒有返回值類型聲明
析構(gòu)函數(shù)在對象銷毀時自動被調(diào)用
代碼示例:
#include
class Test
{
int mi;
public:
Test(int i)
{
mi = i;
printf("Test(): %d\n", mi);
}
~Test()
{
printf("~Test(): %d\n", mi);
}
};
int main()
{
Test t(1);
Test* pt = new Test(2);
delete pt;
return 0;
}
輸出結(jié)果:
Test(): 1
Test(): 2
~Test(): 2
~Test(): 1
3、析構(gòu)函數(shù)的定義準(zhǔn)則:
當(dāng)類中自定義了構(gòu)造函數(shù),并且析構(gòu)函數(shù)中使用了系統(tǒng)資源(比如說,內(nèi)存的申請,文件打開),那么就需要自定義析構(gòu)函數(shù)了。
“c++對象構(gòu)造順序和析構(gòu)函數(shù)舉例分析”的內(nèi)容就介紹到這里了,感謝大家的閱讀。如果想了解更多行業(yè)相關(guān)的知識可以關(guān)注創(chuàng)新互聯(lián)網(wǎng)站,小編將為大家輸出更多高質(zhì)量的實用文章!