C++的深拷貝與淺拷貝

拷貝構(gòu)造函數(shù)

拷貝構(gòu)造函數(shù)是使用類對(duì)象的引用作為參數(shù)的構(gòu)造函數(shù),它能夠?qū)?shù)的屬性值拷貝給新的對(duì)象,完成新對(duì)象的初始化。
通常在一下三種情況下,程序會(huì)自動(dòng)調(diào)用拷貝構(gòu)造函數(shù)。

1.使用一個(gè)對(duì)象初始化另一個(gè)對(duì)象

#include <iostream>
#include<string>
using namespace std;
class Car
{
    public:
        Car(){};    //初始化構(gòu)造函數(shù)
        Car(string name, int seats);
        Car(Car &con_refcar);
        ~Car();    //析構(gòu)函數(shù)
    private:
        string m_name;
        int m_seats;
};
Car::Car(string name, int seats)
{
    m_name = name;
    m_seats = seats;
}
Car::Car(Car &con_refcar)
{
    m_name = con_refcar.m_name;          
    m_seats = con_refcar.m_seats;
}
Car::~Car() {}
int main()
{
    Car mynewcar("rrrr2", 4);
    Car myseccar(mynewcar);   //用一個(gè)對(duì)象對(duì)另一個(gè)對(duì)象初始化
    return 0;
}

2.對(duì)象作為實(shí)參傳遞給函數(shù)參數(shù)

#include <iostream>
#include<string>
using namespace std;
class Car
{
    public:
        Car(){};    //初始化構(gòu)造函數(shù)
        Car(string name, int seats);
        Car(Car &con_refcar);
        void print();
        ~Car();    //析構(gòu)函數(shù)
    private:
        string m_name;
        int m_seats;
};
Car::Car(string name, int seats)
{
    m_name = name;
    m_seats = seats;
}
Car::Car(Car &con_refcar)
{
    m_name = con_refcar.m_name;          
    m_seats = con_refcar.m_seats;
}
Car::~Car() {}
void Car::print()
{
    cout<<"name: "<<m_name<<endl;
    cout<<"sizes: "<<m_seats<<endl;
}
void print_carinfo(Car carinfo)  //對(duì)象最為實(shí)參傳遞給函數(shù)
{
    carinfo.print();
}
int main()
{
    Car mynewcar("rrrr2", 4);
    print_carinfo(mynewcar);  //調(diào)用該函數(shù)
    return 0;
}

3.函數(shù)返回值為類對(duì)象,創(chuàng)建臨時(shí)對(duì)象作為返回值

#include <iostream>
#include<string>
using namespace std;
class Car
{
    public:
        Car(){};    //初始化構(gòu)造函數(shù)
        Car(string name, int seats);
        Car(Car &con_refcar);
        Car get_carinfo();     //****
        void print();
        ~Car();    //析構(gòu)函數(shù)
    private:
        string m_name;
        int m_seats;
};
Car::Car(string name, int seats)
{
    
    m_name = name;
    m_seats = seats;
}
Car::Car(Car &con_refcar)
{

    m_name = con_refcar.m_name;          
    m_seats = con_refcar.m_seats;
}
Car::~Car()
{
}
void Car::print()
{
    cout<<"name: "<<m_name<<endl;
    cout<<"sizes: "<<m_seats<<endl;
}
Car Car::get_carinfo()    //關(guān)鍵函數(shù)
{
    Car tmp(m_name, m_seats);      //定義類對(duì)象
    return tmp;       //返回類對(duì)象
} 
int main()
{
    Car mynewcar("rrrr2", 4);
    Car ret;
    ret = mynewcar.get_carinfo();     //ret接受返回的類對(duì)象
    ret.print();
    return 0;
}

以上都是淺拷貝, 淺拷貝有個(gè)特點(diǎn)就是:類的私有成員不需要new出新的空間,像上面的m_name都是用string類型;如果換成char類型,上面的程序就會(huì)出錯(cuò),原因是,淺拷貝并未為拷貝對(duì)象開(kāi)辟空間,只是讓拷貝對(duì)象的地址指向被拷貝對(duì)象的地址,相當(dāng)于“引用”。為了解決這個(gè)問(wèn)題,就要用到深拷貝!

深拷貝

#include <iostream>
#include<string>
using namespace std;
class Car
{
    public:
        Car(char *name, int seats);     
        Car(Car &con_refcar);
        ~Car();
    private:
        char *m_name;     //char型數(shù)據(jù)成員
        int m_seats;
};
Car::Car(char *name, int seats)
{
    int len = strlen(name) + 1;
    m_name = new char[len];      //每個(gè)對(duì)象初始化都要臨時(shí)開(kāi)劈空間
    strcpy(m_name, name );      //字符串之間賦值要用strcpy()函數(shù)
    m_seats = seats;
}
Car::Car(Car &con_refcar)       //深拷貝
{

    m_name = new char[strlen(con_refcar.m_name)+1];    //淺拷貝無(wú)需開(kāi)劈空間,數(shù)據(jù)成員賦值需要開(kāi)辟空間的都只能用深拷貝實(shí)現(xiàn)!
    strcpy(m_name,con_refcar.m_name);       
    m_seats = con_refcar.m_seats;
}
Car::~Car()
{
    delete[] m_name;
}
int main()
{
    char c[] = "rrrr2";
    Car mynewcar(c, 4);
    Car myseccar(mynewcar);
    return 0;
}

若有錯(cuò),望指出

?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
【社區(qū)內(nèi)容提示】社區(qū)部分內(nèi)容疑似由AI輔助生成,瀏覽時(shí)請(qǐng)結(jié)合常識(shí)與多方信息審慎甄別。
平臺(tái)聲明:文章內(nèi)容(如有圖片或視頻亦包括在內(nèi))由作者上傳并發(fā)布,文章內(nèi)容僅代表作者本人觀點(diǎn),簡(jiǎn)書系信息發(fā)布平臺(tái),僅提供信息存儲(chǔ)服務(wù)。

相關(guān)閱讀更多精彩內(nèi)容

  • 前言 把《C++ Primer》[https://book.douban.com/subject/25708312...
    尤汐Yogy閱讀 9,698評(píng)論 1 51
  • C++文件 例:從文件income. in中讀入收入直到文件結(jié)束,并將收入和稅金輸出到文件tax. out。 檢查...
    SeanC52111閱讀 3,119評(píng)論 0 3
  • C++11的新特性具有廣泛的可用性,可以與其他已有的,或者新增的語(yǔ)言特性結(jié)合起來(lái)進(jìn)行自由的組合,或者提升已有特性的...
    認(rèn)真學(xué)計(jì)算機(jī)閱讀 1,632評(píng)論 0 6
  • 推門還是敲門 有門還是沒(méi)門 一個(gè)站在夢(mèng)里的囈語(yǔ) 一個(gè)躺在囈語(yǔ)的夢(mèng)里 一只鳥(niǎo)撲向月光 一棵樹(shù)倒在夜里 推門的是一個(gè)僧...
    李唐的小詩(shī)閱讀 295評(píng)論 0 4
  • 寶貝,再過(guò)兩天你就一歲了,媽媽很感慨,鬧人的小姑娘居然已經(jīng)一歲了,真快啊。這一年里,媽媽哭過(guò)無(wú)數(shù)次也笑過(guò)無(wú)數(shù)次...
    香草五月閱讀 203評(píng)論 0 0

友情鏈接更多精彩內(nèi)容