日韩性视频-久久久蜜桃-www中文字幕-在线中文字幕av-亚洲欧美一区二区三区四区-撸久久-香蕉视频一区-久久无码精品丰满人妻-国产高潮av-激情福利社-日韩av网址大全-国产精品久久999-日本五十路在线-性欧美在线-久久99精品波多结衣一区-男女午夜免费视频-黑人极品ⅴideos精品欧美棵-人人妻人人澡人人爽精品欧美一区-日韩一区在线看-欧美a级在线免费观看

歡迎訪問 生活随笔!

生活随笔

當(dāng)前位置: 首頁 > 人文社科 > 生活经验 >内容正文

生活经验

C++ 拷贝构造函数和重载赋值运算符的区别

發(fā)布時(shí)間:2023/11/27 生活经验 31 豆豆
生活随笔 收集整理的這篇文章主要介紹了 C++ 拷贝构造函数和重载赋值运算符的区别 小編覺得挺不錯(cuò)的,現(xiàn)在分享給大家,幫大家做個(gè)參考.

文章目錄

      • 拷貝構(gòu)造函數(shù)
      • 重載賦值運(yùn)算符

賦值運(yùn)算符和拷貝構(gòu)造函數(shù)最大區(qū)別是賦值運(yùn)算符沒有新的對(duì)象生成,而拷貝構(gòu)造函數(shù)會(huì)生成新的對(duì)象。
為了更加形象 準(zhǔn)確得描述 賦值運(yùn)算符和拷貝構(gòu)造函數(shù)得區(qū)別,將詳細(xì)通過代碼展示兩者之間得差異。

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

首先從構(gòu)造函數(shù)說起,在C++面向?qū)ο蟮脑O(shè)計(jì)中,每一個(gè)對(duì)象代表一個(gè)抽象集合的實(shí)體,此時(shí)每一個(gè)實(shí)體在當(dāng)前運(yùn)行的進(jìn)程中是需要對(duì)應(yīng)的內(nèi)存空間,即對(duì)象存在則有空間。為此,C++引入構(gòu)造函數(shù)來實(shí)例化對(duì)象,并讓編譯器為該對(duì)象向操作系統(tǒng)申請(qǐng)對(duì)應(yīng)的空間,從而能夠存在于操作系統(tǒng)之中。

拷貝構(gòu)造函數(shù)則是為了將老對(duì)象的數(shù)據(jù)成員一一賦值給新的對(duì)象數(shù)據(jù)成員的一種構(gòu)造函數(shù),即拷貝構(gòu)造函數(shù)的結(jié)果和構(gòu)造函數(shù)一致,都是有新的對(duì)象生成。
查看如下代碼:

#include <iostream>
using namespace std;class A{
public:A(){ cout << "default constructor " << endl;  }A(int a) {num=a;cout << "constructor with param" << endl; }A(const A &a){num=a.num;cout << "copy constructor " << endl;}~A(){ cout << "destructor " << this->num << endl; }void print(){cout << this->num << endl;}private:int num;};
void para_copy(A &a)
{
}
int main()
{A a(100); // 重載構(gòu)造函數(shù)A a1=a; //拷貝構(gòu)造函數(shù)a1.print();A c;//默認(rèn)構(gòu)造函數(shù)return 0;
}

輸出如下:

constructor with param //a 重載構(gòu)造
copy constructor //a1 拷貝構(gòu)造
100
default constructor //c默認(rèn)構(gòu)造
destructor 0 //c析構(gòu)
destructor 100 //a1析構(gòu)
destructor 100 //a析構(gòu)

拷貝構(gòu)造函數(shù)調(diào)用場(chǎng)景如下:

  • 我們?nèi)缟洗a中 一個(gè)對(duì)象由另一個(gè)對(duì)象來初始化
  • 對(duì)象作為函數(shù)參數(shù)
  • 對(duì)象作為函數(shù)返回值
    關(guān)于對(duì)象作為函數(shù)參數(shù)以及返回值時(shí)調(diào)用的拷貝構(gòu)造函數(shù),查看代碼如下
    #include <iostream>
    using namespace std;class A{
    public:A(){ cout << "default constructor " << endl;  }A(int a) {num=a;cout << "constructor with param" << endl; }A(const A &a){num=a.num;cout << "copy constructor " << endl;}~A(){ cout << "destructor " << this->num << endl; }void print(){cout << this->num << endl;}private:int num;};
    void param_copy(A a)
    {cout << "param obj" << endl;
    }
    A return_value()
    {A d(0);cout << "return obj" << endl;return d;
    }
    int main()
    {A c;param_copy(c);return_value();return 0;
    }
    
    輸出如下
    default constructor  //c 默認(rèn)構(gòu)造
    copy constructor // 對(duì)象做參數(shù),拷貝構(gòu)造到臨時(shí)對(duì)象
    param obj
    destructor 0 // 析構(gòu)掉臨時(shí)對(duì)象
    constructor with param //函數(shù)return_value中 d 對(duì)象使用了重載構(gòu)造函數(shù)
    return obj 
    destructor 0 //析構(gòu)掉 d對(duì)象 ,局部變量
    destructor 0 //析構(gòu)掉 c對(duì)象
    

關(guān)于深拷貝和淺拷貝的描述如下:

  1. 通常,默認(rèn)生成的拷貝構(gòu)造函數(shù)和賦值運(yùn)算符,只是簡(jiǎn)單的進(jìn)行值的復(fù)制。如果類的數(shù)據(jù)成員有指針,僅僅通過值傳遞進(jìn)行拷貝構(gòu)造的話會(huì)造成兩個(gè)對(duì)象的成員指針指向同一塊內(nèi)存,當(dāng)兩個(gè)對(duì)象析構(gòu)的時(shí)候會(huì)對(duì)同一個(gè)內(nèi)存釋放兩次,從而會(huì)造成指針空懸。

  2. 深拷貝即以上第二種情況,數(shù)據(jù)成員中有指針變量的時(shí)候拷貝構(gòu)造函數(shù)使用深拷貝,即構(gòu)造函數(shù)中重新指定初始化對(duì)象的地址空間。

    代碼如下:

    #include <iostream>
    using namespace std;class A{
    public:A(){ p=new int(10);cout << "default constructor " << endl;  }//A(int a) {num=a;cout << "constructor with param" << endl; }A(const A &a){num=a.num;p=new int(10);*p=*(a.p);cout << "copy constructor " << endl;}~A(){ cout << "destructor " << this->num << endl; }void print(){if(p!=NULL){delete p;cout << this->num << endl;}}private:int num;int *p;};
    void param_copy(A a)
    {cout << "param obj" << endl;
    }
    int main()
    {A c;A b(c);return 0;
    }
    

重載賦值運(yùn)算符

賦值運(yùn)算符和拷貝構(gòu)造函數(shù)最大區(qū)別即是賦值運(yùn)算符沒有新的對(duì)象生成,而拷貝構(gòu)造函數(shù)會(huì)生成新的對(duì)象。

#include <iostream>
using namespace std;class Person
{
public:Person(){}Person(const Person& p){cout << "Copy Constructor" << endl;}Person& operator=(const Person& p){cout << "Assign" << endl;return *this;}private:int age;string name;
};void f(Person p)
{return;
}Person f1()
{Person p;return p;
}int main()
{Person p;Person p1 = p;    // Acout <<" p1 addr " <<  &p1 << endl;Person p2;cout <<" p2 addr " <<  &p2 << endl;p2 = p;           // Bcout <<" p2 addr after asign " <<  &p2 << endl;f(p2);            // C f函數(shù)參數(shù)cout <<" p2 addr after asign " <<  &p2 << endl;p2 = f1();        // D f1返回值為改對(duì)象,則先進(jìn)行拷貝構(gòu)造,在將返回的對(duì)象賦值給p2cout <<" p2 addr after asign " <<  &p2 << endl;Person p3 = f1(); // E 生成新對(duì)象,則為拷貝構(gòu)造函數(shù)cout <<" p3 addr " <<  &p3 << endl;getchar();return 0;
}

輸出如下:

Copy Constructor
Assign
Copy Constructor
Copy Constructor
Assign
Copy Constructor

總結(jié)

以上是生活随笔為你收集整理的C++ 拷贝构造函数和重载赋值运算符的区别的全部?jī)?nèi)容,希望文章能夠幫你解決所遇到的問題。

如果覺得生活随笔網(wǎng)站內(nèi)容還不錯(cuò),歡迎將生活随笔推薦給好友。