日本免费高清视频-国产福利视频导航-黄色在线播放国产-天天操天天操天天操天天操|www.shdianci.com

學無先后,達者為師

網站首頁 編程語言 正文

淺析C++淺拷貝與深拷貝的聯系和區別_C 語言

作者:憶盅 ? 更新時間: 2022-11-03 編程語言

文章簡述

c++中構造函數分為三類:無參構造、帶參構造和拷貝構造,其中拷貝構造可分為默認拷貝(淺拷貝)、深拷貝,在程序中,這里我們主要講淺拷貝和深拷貝的聯系和區別。

首先,我們要明白拷貝至少需要兩個對象,并且在拷貝時,我們可以用const來保護原對象的內容,具體用法:----- <類名>(const<類名> 對象) -----進行復制的對象 ,當我們使用棧開辟空間進行復制時,不會出現意外,如下:

/*===============================================
*   文件名稱:shallow_deep_copy.cpp
*   創 建 者:     
*   創建日期:
*   描    述:
================================================*/
#include <iostream>
using namespace std;
class student
{
    private:
        string name;       //--------------//
        int age;
    public:
        student()    //出現帶參構造,需要默認構造
        {
            cout << "默認構造" << endl;
        }
        student(string m_name, int m_age)
        {
            cout << "name:" << m_name << endl << "age:" << m_age << endl;
            cout << "帶參構造" << endl;
        }
        ~student()
        {
            cout << "析構函數" << endl;
        }
};
void test1()
{
    student s1 = student("tom", 12);
    student s2 = s1;        //利用棧進行默認復制
}
int main()
{
    test1();        //引用函數.
    return 0;
}

結果如圖:

name:tom

age:12

帶參構造

析構函數

析構函數

我們可以發現,復制后進行輸出時只有一個帶參構造和兩個析構函數,說明了棧中系統自動申請又釋放了兩次空間,但是這個操作卻在自己創建空間(堆)時,卻是錯誤的,此時的代碼又有所不同:

/*===============================================
*   文件名稱:shallow_deep_copy.cpp
*   創 建 者:     
*   創建日期:
*   描    述:
================================================*/
#include <iostream>
using namespace std;
class student
{
    private:
        string name;
        //int age;
        int *age;    //定義指針age
    public:
        student()
        {
            cout << "默認構造" << endl;
        }
#if 0      //------------------------------------------
        student(string m_name, int m_age)
        {
            cout << "name:" << m_name << endl << "age:" << m_age << endl;
            cout << "帶參構造" << endl;
        }
#endif    //-------------------------------------------
        student(int m_age)
        {
            this->age = new int(m_age);
            cout << "開辟空間" << endl;
        }
        ~student()
        {   
            delete age;    //開辟使用完成,在析構進行釋放age操作
            cout << "析構函數" << endl;
        }
        int get_age()
        {
            return *age;
        }
};
void test1()
{
    //student s1 = student("tom", 12);
    //student s2 = s1;
    student s1(10);    //定義年齡為10,進行復制
    student s2 = s1;
}
int main()
{
    test1();       //調用函數
    return 0;
}

結果:

開辟空間

析構函數

free(): double free detected in tcache 2

已放棄 (核心已轉儲)

這里我們只調用了*age這個參數,但已經很明顯的看到結果,錯誤信息為兩次釋放該空間,在開辟這片空間時,又進行重復釋放操作,很明顯這是系統所不允許的。

接下來進行深拷貝:

/*===============================================
*   文件名稱:shallow_deep_copy.cpp
*   創 建 者:     
*   創建日期:
*   描    述:
================================================*/
#include <iostream>
using namespace std;
class student
{
    private:
        string name;
        //int age;
        int *age;
    public:
        student()
        {
            cout << "默認構造" << endl;
        }
#if 0   //--------------------------------------
        student(string m_name, int m_age)
        {
            cout << "name:" << m_name << endl << "age:" << m_age << endl;
            cout << "帶參構造" << endl;
        }
#endif  //--------------------------------------
        student(int m_age)
        {
            this->age = new int(m_age);
            cout << "開辟空間" << endl;
        }
        //-----------深淺拷貝-------------------
        //student(const student &s)
        //{
        //    this->age = s.age;
        //    cout << "淺拷貝" << endl;
        //
        //}
        student(const student &s)
        {
            this->age = new int(*s.age); //創建一片新的空間進行儲存
            cout << "深拷貝" << endl;
        }
        //--------------------------------------
        ~student()
        {   
            delete age;
            cout << "析構函數" << endl;
        }
        int get_age()
        {
            return *age;
        }
};
void test1()
{
    //student s1 = student("tom", 12);
    //student s2 = s1;
    student s1(10);
    student s2 = s1;
}
int main()
{
    test1();
    return 0;
}

開辟空間

深拷貝

析構函數

析構函數

此時結果為正確,這里釋放的是兩片一樣內容但地址不一樣的空間。

到此,*我們就能總結出:淺拷貝(默認拷貝)是兩個指針申請同一片空間地址,而在釋放時,也是同一片堆內存;深拷貝是對指針所指向的內容進行拷貝,同時兩個指針指向的是不同空間地址,所以在釋放時需要釋放兩次。

原文鏈接:https://blog.csdn.net/qq_48866804/article/details/126692936

欄目分類
最近更新