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

C++構(gòu)造函數(shù)的一些注意事項總結(jié)

 更新時間:2021年11月01日 14:47:21   作者:學渣的C/C++  
構(gòu)造函數(shù)是創(chuàng)建類對象,并且在創(chuàng)建完成前,對類進行初始化的特殊函數(shù),下面這篇文章主要給大家介紹了關(guān)于C++構(gòu)造函數(shù)的一些注意事項,需要的朋友可以參考下

1、匿名對象

首先應(yīng)該明確匿名對象,匿名對象是之沒有對象名,調(diào)用完構(gòu)造函數(shù)后即析構(gòu)的對象。下面通過代碼捕捉類的構(gòu)造函數(shù)和析構(gòu)函數(shù),以進行說明:

#include <iostream>
using namespace std;

class Solution{
public:
    Solution(int a, int b):m_num1(a), m_num2(b) {
        cout << "有參構(gòu)造函數(shù)的調(diào)用" << endl;
    };
    Solution(const Solution& s):m_num1(s.m_num1), m_num2(s.m_num2){
        cout << "拷貝構(gòu)造函數(shù)的調(diào)用" << endl;
    } 
    ~Solution(){
        cout << "析構(gòu)函數(shù)的調(diào)用" << endl;
    }
private:
    int m_num1;
    int m_num2;
};

int main()
{
    Solution(8,9); // Solution(8,9) 匿名對象
    
    system("pause");
    return 0;
}

代碼運行結(jié)果為:

通過代碼運行結(jié)果可以看到,創(chuàng)建匿名對象的時候,調(diào)用了類的構(gòu)造函數(shù),隨后立即調(diào)用了析構(gòu)函數(shù)。我們可以直接利用匿名對象進行初始化類的成員的初始化,代碼如下:

#include <iostream>
using namespace std;

class Solution{
public:
    Solution(int a, int b):m_num1(a), m_num2(b) {
        cout << "有參構(gòu)造函數(shù)的調(diào)用" << endl;
    };
    Solution(const Solution& s):m_num1(s.m_num1), m_num2(s.m_num2){
        cout << "拷貝構(gòu)造函數(shù)的調(diào)用" << endl;
    } 
    ~Solution(){
        cout << "析構(gòu)函數(shù)的調(diào)用" << endl;
    }

    int m_num1;
    int m_num2;
};

int main()
{
    Solution s1(Solution(8,9));
    // Solution s1 = Solution(8,9); //顯式 Solution(8,9) 匿名對象初始化類成員
    // Solution s1 = {8,9};        //{8,9}等價于Solution(8,9)
    cout << "s1.m_num1 = " << s1.m_num1 << endl;
    cout << "s1.m_num2 = " << s1.m_num2 << endl;   
    system("pause");
    return 0;
}

運行結(jié)果如下:

代碼調(diào)用了一次構(gòu)造函數(shù),可見匿名對象可以初始化類成員,就是將匿名對象轉(zhuǎn)化成了s1對象,這里需要與拷貝構(gòu)造函數(shù)區(qū)分開:

#include <iostream>
using namespace std;

class Solution{
public:
    Solution(int a, int b):m_num1(a), m_num2(b) {
        cout << "有參構(gòu)造函數(shù)的調(diào)用" << endl;
    };
    Solution(const Solution& s):m_num1(s.m_num1), m_num2(s.m_num2){
        cout << "拷貝構(gòu)造函數(shù)的調(diào)用" << endl;
    } 
    ~Solution(){
        cout << "析構(gòu)函數(shù)的調(diào)用" << endl;
    }

    int m_num1;
    int m_num2;
};

int main()
{
    Solution s1(10,11);
    Solution s2(s1);
    cout << "s2.m_num1 = " << s2.m_num1 << endl;
    cout << "s2.m_num2 = " << s2.m_num2 << endl;
    system("pause");
    return 0;
}

代碼運行結(jié)果為:

對比以上兩個代碼可以發(fā)現(xiàn),通過匿名對象初始化類成員并不是拷貝構(gòu)造,只是一種替換,通過匿名對象初始化類成員并不會調(diào)用拷貝構(gòu)造函數(shù)。

2、拷貝構(gòu)造函數(shù)的調(diào)用時機

今年秋招筆試題最愛考查構(gòu)造函數(shù)的調(diào)用時機,通常會結(jié)合繼承和多態(tài)來考察,這里先說明一下拷貝構(gòu)造函數(shù)的調(diào)用時機,后面再詳細說明帶繼承和多態(tài)的構(gòu)造函數(shù)調(diào)用時機。

一、使用一個已經(jīng)創(chuàng)建的對象來初始化一個新對象,如上面的代碼,創(chuàng)建對象s1的時候調(diào)用了有參構(gòu)造函數(shù),通過s1來初始化s2的時候調(diào)用了拷貝構(gòu)造。

二、函數(shù)的參數(shù)是需要值傳遞的對象的時候

三、函數(shù)返回對象的時候

下面通過代碼驗證,當函數(shù)的參數(shù)是一個需要值傳遞的對象的情況:

#include <iostream>
using namespace std;

class Solution{
public:
    Solution(int a, int b):m_num1(a), m_num2(b) {
        cout << "有參構(gòu)造函數(shù)的調(diào)用" << endl;
    };
    Solution(const Solution& s):m_num1(s.m_num1), m_num2(s.m_num2){
        cout << "拷貝構(gòu)造函數(shù)的調(diào)用" << endl;
    } 
    ~Solution(){
        cout << "析構(gòu)函數(shù)的調(diào)用" << endl;
    }
public:
    int m_num1;
    int m_num2;
};

void showClassNum(Solution s) {
    cout << s.m_num1 << endl;
    cout << s.m_num2 << endl;
}

int main()
{
    Solution s1(10,11);
    showClassNum(s1);
    system("pause");
    return 0;
}

代碼運行結(jié)果為:

通過代碼運行結(jié)果可以看到,s1對象調(diào)用了有參構(gòu)造函數(shù),當把s1傳給函數(shù)的參數(shù)s的時候調(diào)用了拷貝構(gòu)造函數(shù),函數(shù)執(zhí)行完調(diào)用了s對象的析構(gòu)函數(shù)。

當函數(shù)的返回值是一個對象的時候,也會調(diào)用拷貝構(gòu)造函數(shù):

#include <iostream>
using namespace std;

class Solution{
public:
    Solution(int a, int b):m_num1(a), m_num2(b) {
        cout << "有參構(gòu)造函數(shù)的調(diào)用" << endl;
    };
    Solution(const Solution& s):m_num1(s.m_num1), m_num2(s.m_num2){
        cout << "拷貝構(gòu)造函數(shù)的調(diào)用" << endl;
    } 
    ~Solution(){
        cout << "析構(gòu)函數(shù)的調(diào)用" << endl;
    }

    void changeNum(int a, int b) {
        m_num1 = a;
        m_num2 = b;
    }

    void showNum() {
        cout << "m_num1 = " << m_num1 << endl;
        cout << "m_num2 = " << m_num2 << endl;
    }
public:
    int m_num1;
    int m_num2;
};

Solution clearClassNum(Solution s) {
    s.changeNum(0,0);
    return s;
}

int main()
{
    Solution s1 (10,10);
    s1 = clearClassNum (s1);
    s1.showNum();
    system("pause");
    return 0;
}

代碼運行結(jié)果為:

從代碼運行結(jié)果可以看出來,函數(shù)傳參的時候調(diào)用了拷貝構(gòu)造,然后函數(shù)返回一個對象的時候的也調(diào)用了拷貝構(gòu)造。

需要注意的是,函數(shù)要返回對象的時候,不要使用引用的方式返回,因為函數(shù)的內(nèi)的變量存放在堆棧區(qū),在函數(shù)執(zhí)行完畢后就會釋放這塊內(nèi)存,引用就會出現(xiàn)問題。

3、深拷貝和淺拷貝

面試的時候比較喜歡問的問題,首先淺拷貝就是我們常用的拷貝,實現(xiàn)了對象成員的拷貝,深拷貝就是在堆區(qū)申請空間,然后再進行拷貝操作,淺拷貝可以由編譯器完成,但是深拷貝需要我們自己完成,就是有在堆區(qū)開辟的內(nèi)存,就一定要自己提供拷貝構(gòu)造函數(shù),防止淺拷貝帶來的重復(fù)內(nèi)存釋放問題。代碼驗證如下:

#include <iostream>
using namespace std;

class Solution{
public:
    Solution(int a, int b):m_num1(a), pm_num2(new int(b)) {
        cout << "有參構(gòu)造函數(shù)的調(diào)用" << endl;
    };
      //如果不利用深拷貝在堆區(qū)創(chuàng)建新內(nèi)存,會導(dǎo)致淺拷貝帶來的重復(fù)釋放堆區(qū)問題,導(dǎo)致程序出錯
    Solution(const Solution& s):m_num1(s.m_num1), pm_num2(new int(*s.pm_num2)) {
        cout << "拷貝構(gòu)造函數(shù)的調(diào)用" << endl;
    }
    ~Solution(){
        cout << "析構(gòu)函數(shù)的調(diào)用,釋放堆區(qū)申請的內(nèi)存" << endl;
        if (pm_num2 != nullptr) {
            delete pm_num2;
        }
    }

    void changeNum(int a, int b) {
        m_num1 = a;
        *pm_num2 = b;
    }

    void showNum() {
        cout << "m_num1 = " << m_num1 << endl;
        cout << "m_num2 = " << *pm_num2 << endl;
    }
public:
    int m_num1;
    int* pm_num2;
};

void func()
{
    Solution s1 (10,10);
    Solution s2(s1);
    s2.showNum();
}

int main()
{

    func();
    system("pause");
    return 0;
}

代碼運行結(jié)果為:

總結(jié)

到此這篇關(guān)于C++構(gòu)造函數(shù)注意事項的文章就介紹到這了,更多相關(guān)C++構(gòu)造函數(shù)注意事項內(nèi)容請搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關(guān)文章希望大家以后多多支持腳本之家!

相關(guān)文章

  • Qt實現(xiàn)簡單TCP服務(wù)器

    Qt實現(xiàn)簡單TCP服務(wù)器

    這篇文章主要為大家詳細介紹了Qt實現(xiàn)簡單TCP服務(wù)器,文中示例代碼介紹的非常詳細,具有一定的參考價值,感興趣的小伙伴們可以參考一下
    2022-08-08
  • 用C語言實現(xiàn)簡單掃雷游戲

    用C語言實現(xiàn)簡單掃雷游戲

    這篇文章主要為大家詳細介紹了用C語言實現(xiàn)簡單掃雷游戲,文中示例代碼介紹的非常詳細,具有一定的參考價值,感興趣的小伙伴們可以參考一下
    2021-07-07
  • C語言 野指針與空指針專篇解讀

    C語言 野指針與空指針專篇解讀

    全網(wǎng)最接地氣的C語言野指針介紹,此處對于野指針與空指針知識點做一些簡要的介紹,作者實屬初學,寫博客也是作者學習的一個過程,難免文章中有內(nèi)容理解不到位或者有不當之處,還請朋友們不吝指正,希望大家多多給予支持,贈人玫瑰,手有余香
    2021-11-11
  • C語言中基礎(chǔ)小問題詳細介紹

    C語言中基礎(chǔ)小問題詳細介紹

    這篇文章詳細介紹了C語言中基礎(chǔ)小問題,有需要的朋友可以參考一下
    2013-10-10
  • C++中string的模擬實現(xiàn)

    C++中string的模擬實現(xiàn)

    這篇文章主要為大家詳細介紹了C++中string的模擬實現(xiàn),感興趣的小伙伴們可以參考一下
    2016-08-08
  • VC++?2019?"const?char*"類型的實參與"LPCTSTR"類型的形參不兼容解決

    VC++?2019?"const?char*"類型的實參與"LPCTSTR"

    這篇文章主要給大家介紹了關(guān)于VC++?2019?"const?char*"類型的實參與"LPCTSTR"類型的形參不兼容的解決方法,文中通過圖文介紹的非常詳細,對大家的學習或者工作具有一定的參考學習價值,需要的朋友可以參考下
    2023-03-03
  • 解析wprintf 中使用%I64d格式化輸出LONGLONG的詳細介紹

    解析wprintf 中使用%I64d格式化輸出LONGLONG的詳細介紹

    本篇文章是對wprintf 中使用%I64d格式化輸出LONGLONG進行了詳細的分析介紹,需要的朋友參考下
    2013-05-05
  • Qt5.14.2使用虛擬鍵盤的關(guān)鍵代碼

    Qt5.14.2使用虛擬鍵盤的關(guān)鍵代碼

    對于Qwidget程序,使用qtvirtualkeyboard彈出鍵盤之后,鍵盤會浮于表面。使用VirtualkeyboardPushView模塊,自動根據(jù)情況把輸入視圖往上面推移,這篇文章主要介紹了Qt5.14.2使用虛擬鍵盤的關(guān)鍵代碼,需要的朋友可以參考下
    2022-09-09
  • C++中LibCurl庫使用流程及配置詳解

    C++中LibCurl庫使用流程及配置詳解

    libcurl是一個跨平臺的開源網(wǎng)絡(luò)傳輸庫,它支持許多協(xié)議,包括HTTP、HTTPS、FTP、FTPS以及許多其他協(xié)議和文件傳輸方式,本文給大家詳細介紹了C++中LibCurl庫使用流程及配置,需要的朋友可以參考下
    2024-02-02
  • C語言程序環(huán)境和預(yù)處理詳解分析

    C語言程序環(huán)境和預(yù)處理詳解分析

    大家有沒有想過,在vs2019的編譯器上只要按下Ctrl+F5,一個test.c的源程序就能變成一個.exe的可執(zhí)行程序,這其中是如何通過編譯產(chǎn)生的呢,本章就和大家一起把其中的知識和重點的預(yù)處理一起學習一下
    2022-03-03

最新評論