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

學無先后,達者為師

網站首頁 編程語言 正文

C++簡明圖解分析淺拷貝與深拷貝_C 語言

作者:Bright-SKY ? 更新時間: 2022-07-30 編程語言

類中有指針成員 才會討論 淺拷貝 和深拷貝問題。

淺拷貝(單純值拷貝)

#include <iostream>
#include <string.h>
#include <stdlib.h>
using namespace std;
class Person
{
public:
    char *m_name;
public:
    Person(char *name)
    {
        cout<<"有參構造"<<endl;
        m_name = (char *)calloc(1,strlen(name)+1);
        if(m_name == NULL)
        {
            cout<<"空間申請失敗"<<endl;
            exit(-1);
        }
        strcpy(m_name, name);
    }
    ~Person()
    {
        cout<<"析構函數"<<endl;
        //釋放指針成員 指向的堆區空間
        if(m_name != NULL)
        {
            free(m_name);
            m_name = NULL;
        }
        cout<<"-----001------"<<endl;
    }
};
int main(int argc, char *argv[])
{
    Person ob1("lucy");
    Person ob2 = ob1;//拷貝構造(默認是淺拷貝)
    cout<<"ob2.m_name = "<<ob2.m_name<<endl;
    return 0;
}

深拷貝

必須在拷貝構造中給ob2.m_name申請空間

#include <iostream>
#include <string.h>
#include <stdlib.h>
using namespace std;
class Person
{
public:
    char *m_name;
public:
    Person(char *name)
    {
        cout<<"有參構造"<<endl;
        m_name = (char *)calloc(1,strlen(name)+1);
        if(m_name == NULL)
        {
            cout<<"空間申請失敗"<<endl;
            exit(-1);
        }
        strcpy(m_name, name);
    }
    Person(const Person &ob)
    {
        cout<<"拷貝構造函數(深拷貝)"<<endl;
        m_name = (char *)calloc(1, strlen(ob.m_name)+1);
        if(m_name == NULL)
        {
            cout<<"空間申請失敗"<<endl;
            exit(-1);
        }
        strcpy(m_name, ob.m_name);
    }
    ~Person()
    {
        cout<<"析構函數"<<endl;
        //釋放指針成員 指向的堆區空間
        if(m_name != NULL)
        {
            free(m_name);
            m_name = NULL;
        }
    }
};
int main(int argc, char *argv[])
{
    Person ob1("lucy");
    Person ob2 = ob1;//拷貝構造
    cout<<"ob2.m_name = "<<ob2.m_name<<endl;
    return 0;
}

總結

1、如果類中的成員 指向了堆區空間 一定要記得在析構函數中 釋放該空間

2、如果用戶 不實現 拷貝構造 系統就會提供默認拷貝構造,而默認拷貝構造 只是單純的賦值 容易造成淺拷貝問題

3、用戶記得 要實現:無參構造(初始化數據)、有參構造(賦參數)、拷貝構造(深拷貝) 、析構函數(釋放空間)

拷貝構造函數的調用時機

拷貝構造函數調用的時機:舊對象 給新對象 初始化

class Data
{
public:
    Data()
    {
        cout<<"無參構造"<<endl;
    }
    Data(const Data &ob)
    {
        cout<<"拷貝構造"<<endl;
    }
    ~Data()
    {
        cout<<"析夠函數"<<endl;
    }
};

情形1:舊對象給新對象初始化

Data ob1;
Data ob2 = ob1;//調用拷貝構造

情形2:普通對象作為函數的參數

void fun01(Data ob)//Data ob=ob1  發生拷貝構造
{
}
int main(int argc, char *argv[])
{
    Data ob1;
    fun01(ob1);
    return 0;
}

情形3:普通對象 作為函數的返回值

#include <iostream>
using namespace std;
Data fun01(void)
{
    Data ob1;
    return ob1;
}
int main(int argc, char *argv[])
{
    Data ob = fun01();
    return 0;
}

vs下會發生拷貝構造:

Qt、linux不會發生拷貝:

原文鏈接:https://blog.csdn.net/qq_34981463/article/details/124994749

欄目分類
最近更新