溫馨提示×

溫馨提示×

您好,登錄后才能下訂單哦!

密碼登錄×
登錄注冊×
其他方式登錄
點擊 登錄注冊 即表示同意《億速云用戶服務條款》

c++對象構(gòu)造順序和析構(gòu)函數(shù)舉例分析

發(fā)布時間:2021-11-24 16:37:15 來源:億速云 閱讀:124 作者:iii 欄目:大數(shù)據(jù)

本篇內(nèi)容介紹了“c++對象構(gòu)造順序和析構(gòu)函數(shù)舉例分析”的有關知識,在實際案例的操作過程中,不少人都會遇到這樣的困境,接下來就讓小編帶領大家學習一下如何處理這些情況吧!希望大家仔細閱讀,能夠?qū)W有所成!

一、對象的構(gòu)造順序:

1、對于局部對象:

當程序執(zhí)行流到達對象的定義語句時進行構(gòu)造。下面還是用代碼來解析這句話:

#include <stdio.h>

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

 

這里我們可以看出當程序流執(zhí)行到相應的構(gòu)造對象的那條執(zhí)行語句時,就會調(diào)用構(gòu)造函數(shù)(或者拷貝構(gòu)造函數(shù))。goto語句想必大家不陌生,但是都害怕這玩意,下面我們加入goto語句看看會產(chǎn)生什么現(xiàn)象:

#include <stdio.h>
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í)行到,這里這樣寫的目的是為了引出,當你使用goto語句,把對象給屏蔽了,后面你不能使用這個對象了,不然程序會出現(xiàn)大問題:

#include <stdio.h>
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、對于堆對象:

  • 當程序執(zhí)行流到達new語句時創(chuàng)建對象

  • 使用new創(chuàng)建對象將自動觸發(fā)構(gòu)造函數(shù)的調(diào)用

代碼演示:

#include <stdio.h>

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 <stdio.h>

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 <stdio.h>

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ù)的定義準則:

當類中自定義了構(gòu)造函數(shù),并且析構(gòu)函數(shù)中使用了系統(tǒng)資源(比如說,內(nèi)存的申請,文件打開),那么就需要自定義析構(gòu)函數(shù)了。

“c++對象構(gòu)造順序和析構(gòu)函數(shù)舉例分析”的內(nèi)容就介紹到這里了,感謝大家的閱讀。如果想了解更多行業(yè)相關的知識可以關注億速云網(wǎng)站,小編將為大家輸出更多高質(zhì)量的實用文章!

向AI問一下細節(jié)

免責聲明:本站發(fā)布的內(nèi)容(圖片、視頻和文字)以原創(chuàng)、轉(zhuǎn)載和分享為主,文章觀點不代表本網(wǎng)站立場,如果涉及侵權(quán)請聯(lián)系站長郵箱:is@yisu.com進行舉報,并提供相關證據(jù),一經(jīng)查實,將立刻刪除涉嫌侵權(quán)內(nèi)容。

c++
AI