最新国产好看的视频,伊人天堂AV在线,国产Aaaaaa视频,蜜臀视频在线观看一区,人妻av色图,密臀久久久精品影片,青青视频免费观看毛片,久草在线观看视,国产三级精品色情在线

詳解C++中構(gòu)造函數(shù),拷貝構(gòu)造函數(shù)和賦值函數(shù)的區(qū)別和實現(xiàn)

 更新時間:2019年03月26日 10:18:25   作者:Zmyths  
這篇文章主要介紹了C++中構(gòu)造函數(shù),拷貝構(gòu)造函數(shù)和賦值函數(shù)的區(qū)別和實現(xiàn),文中通過示例代碼介紹的非常詳細(xì),對大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價值,需要的朋友們下面隨著小編來一起學(xué)習(xí)學(xué)習(xí)吧

C++中一般創(chuàng)建對象,拷貝或賦值的方式有構(gòu)造函數(shù),拷貝構(gòu)造函數(shù),賦值函數(shù)這三種方法。下面就詳細(xì)比較下三者之間的區(qū)別以及它們的具體實現(xiàn)

1.構(gòu)造函數(shù)

構(gòu)造函數(shù)是一種特殊的類成員函數(shù),是當(dāng)創(chuàng)建一個類的對象時,它被調(diào)用來對類的數(shù)據(jù)成員進(jìn)行初始化和分配內(nèi)存。(構(gòu)造函數(shù)的命名必須和類名完全相同)

首先說一下一個C++的空類,編譯器會加入哪些默認(rèn)的成員函數(shù)

默認(rèn)構(gòu)造函數(shù)和拷貝構(gòu)造函數(shù)

析構(gòu)函數(shù)

賦值函數(shù)(賦值運算符)

取值函數(shù)

**即使程序沒定義任何成員,編譯器也會插入以上的函數(shù)!

注意:構(gòu)造函數(shù)可以被重載,可以多個,可以帶參數(shù);析構(gòu)函數(shù)只有一個,不能被重載,不帶參數(shù)

而默認(rèn)構(gòu)造函數(shù)沒有參數(shù),它什么也不做。當(dāng)沒有重載無參構(gòu)造函數(shù)時,

A a就是通過默認(rèn)構(gòu)造函數(shù)來創(chuàng)建一個對象

下面代碼為構(gòu)造函數(shù)重載的實現(xiàn)

<span style="font-size:14px;">class A
{
int m_i;
Public:
 A() 
{
 Cout<<”無參構(gòu)造函數(shù)”<<endl;
}
A(int i):m_i(i) {} //初始化列表
}</span>

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

拷貝構(gòu)造函數(shù)是C++獨有的,它是一種特殊的構(gòu)造函數(shù),用基于同一類的一個對象構(gòu)造和初始化另一個對象。

當(dāng)沒有重載拷貝構(gòu)造函數(shù)時,通過默認(rèn)拷貝構(gòu)造函數(shù)來創(chuàng)建一個對象

A a;

A b(a);

A b=a;  都是拷貝構(gòu)造函數(shù)來創(chuàng)建對象b

強調(diào):這里b對象是不存在的,是用a 對象來構(gòu)造和初始化b的??!

先說下什么時候拷貝構(gòu)造函數(shù)會被調(diào)用:

在C++中,3種對象需要復(fù)制,此時拷貝構(gòu)造函數(shù)會被調(diào)用

  1. 1)一個對象以值傳遞的方式傳入函數(shù)體
  2. 2)一個對象以值傳遞的方式從函數(shù)返回
  3. 3)一個對象需要通過另一個對象進(jìn)行初始化

什么時候編譯器會生成默認(rèn)的拷貝構(gòu)造函數(shù):

  1. 1)如果用戶沒有自定義拷貝構(gòu)造函數(shù),并且在代碼中使用到了拷貝構(gòu)造函數(shù),編譯器就會生成默認(rèn)的拷貝構(gòu)造函數(shù)。但如果用戶定義了拷貝構(gòu)造函數(shù),編譯器就不在生成。
  2. 2)如果用戶定義了一個構(gòu)造函數(shù),但不是拷貝構(gòu)造函數(shù),而此時代碼中又用到了拷貝構(gòu)造函數(shù),那編譯器也會生成默認(rèn)的拷貝構(gòu)造函數(shù)。

因為系統(tǒng)提供的默認(rèn)拷貝構(gòu)造函數(shù)工作方式是內(nèi)存拷貝,也就是淺拷貝。如果對象中用到了需要手動釋放的對象,則會出現(xiàn)問題,這時就要手動重載拷貝構(gòu)造函數(shù),實現(xiàn)深拷貝。

下面說說深拷貝與淺拷貝:

  1. 淺拷貝:如果復(fù)制的對象中引用了一個外部內(nèi)容(例如分配在堆上的數(shù)據(jù)),那么在復(fù)制這個對象的時候,讓新舊兩個對象指向同一個外部內(nèi)容,就是淺拷貝。(指針雖然復(fù)制了,但所指向的空間內(nèi)容并沒有復(fù)制,而是由兩個對象共用,兩個對象不獨立,刪除空間存在)
  2. 深拷貝:如果在復(fù)制這個對象的時候為新對象制作了外部對象的獨立復(fù)制,就是深拷貝。

拷貝構(gòu)造函數(shù)重載聲明如下:

A (const A&other)

下面為拷貝構(gòu)造函數(shù)的實現(xiàn):

<span style="font-size:14px;">class A
{
 int m_i
 A(const A& other):m_i(other.m_i)
{
 Cout<<”拷貝構(gòu)造函數(shù)”<<endl;
}
}</span>

3.賦值函數(shù)

當(dāng)一個類的對象向該類的另一個對象賦值時,就會用到該類的賦值函數(shù)。

當(dāng)沒有重載賦值函數(shù)(賦值運算符)時,通過默認(rèn)賦值函數(shù)來進(jìn)行賦值操作

A a;

A b;

b=a; 

強調(diào):這里a,b對象是已經(jīng)存在的,是用a 對象來賦值給b的??!

賦值運算的重載聲明如下:

 A& operator = (const A& other)

通常大家會對拷貝構(gòu)造函數(shù)和賦值函數(shù)混淆,這兒仔細(xì)比較兩者的區(qū)別:

1)拷貝構(gòu)造函數(shù)是一個對象初始化一塊內(nèi)存區(qū)域,這塊內(nèi)存就是新對象的內(nèi)存區(qū),而賦值函數(shù)是對于一個已經(jīng)被初始化的對象來進(jìn)行賦值操作。

<span style="font-size:14px;">class A;
A a;
A b=a;  //調(diào)用拷貝構(gòu)造函數(shù)(b不存在)
A c(a) ;  //調(diào)用拷貝構(gòu)造函數(shù)
 
/****/
 
class A;
A a;
A b;  
b = a ;  //調(diào)用賦值函數(shù)(b存在)</span>

2)一般來說在數(shù)據(jù)成員包含指針對象的時候,需要考慮兩種不同的處理需求:一種是復(fù)制指針對象,另一種是引用指針對象??截悩?gòu)造函數(shù)大多數(shù)情況下是復(fù)制,而賦值函數(shù)是引用對象

3)實現(xiàn)不一樣??截悩?gòu)造函數(shù)首先是一個構(gòu)造函數(shù),它調(diào)用時候是通過參數(shù)的對象初始化產(chǎn)生一個對象。賦值函數(shù)則是把一個新的對象賦值給一個原有的對象,所以如果原來的對象中有內(nèi)存分配要先把內(nèi)存釋放掉,而且還要檢察一下兩個對象是不是同一個對象,如果是,不做任何操作,直接返回。(這些要點會在下面的String實現(xiàn)代碼中體現(xiàn))

?。?!如果不想寫拷貝構(gòu)造函數(shù)和賦值函數(shù),又不允許別人使用編譯器生成的缺省函數(shù),最簡單的辦法是將拷貝構(gòu)造函數(shù)和賦值函數(shù)聲明為私有函數(shù),不用編寫代碼。如:

<span style="font-size:14px;">class A
{
 private:
 A(const A& a); //私有拷貝構(gòu)造函數(shù)
 A& operate=(const A& a); //私有賦值函數(shù)
}</span>

如果程序這樣寫就會出錯:

<span style="font-size:14px;">A a;
A b(a); //調(diào)用了私有拷貝構(gòu)造函數(shù),編譯出錯
 
A b;
b=a; //調(diào)用了私有賦值函數(shù),編譯出錯</span>

所以如果類定義中有指針或引用變量或?qū)ο?,為了避免潛在錯誤,最好重載拷貝構(gòu)造函數(shù)和賦值函數(shù)。

下面以string類的實現(xiàn)為例,完整的寫了普通構(gòu)造函數(shù),拷貝構(gòu)造函數(shù),賦值函數(shù)的實現(xiàn)。String類的基本實現(xiàn)見我另一篇博文。

<span style="font-size:14px;">String::String(const char* str)  //普通構(gòu)造函數(shù)
 
{
 
 cout<<construct<<endl;
 
 if(str==NULL)    //如果str 為NULL,就存一個空字符串“”
 
{
 m_string=new char[1];
 *m_string ='\0';
}
 
 else
 
{
 
 m_string= new char[strlen(str)+1] ;  //分配空間
 strcpy(m_string,str);
 
}
 
}
 
 
String::String(const String&other)  //拷貝構(gòu)造函數(shù)
 
{
 cout<<"copy construct"<<endl;
 m_string=new char[strlen(other.m_string)+1]; //分配空間并拷貝
 strcpy(m_string,other.m_string);
}
 
String & String::operator=(const String& other) //賦值運算符
{
 cout<<"operator =funtion"<<endl ;
 if(this==&other) //如果對象和other是用一個對象,直接返回本身
 {
 return *this;
 }
 delete []m_string; //先釋放原來的內(nèi)存
 m_string= new char[strlen(other.m_string)+1];
 strcpy(m_string,other.m_string);
 return * this;
}</span>

一句話記住三者:

對象不存在,且沒用別的對象來初始化,就是調(diào)用了構(gòu)造函數(shù);

對象不存在,且用別的對象來初始化,就是拷貝構(gòu)造函數(shù)(上面說了三種用它的情況?。?/p>

對象存在,用別的對象來給它賦值,就是賦值函數(shù)。

以上為本人結(jié)合很多資料和圖書整理出來的,將核心的點都系統(tǒng)的理出來,全自己按條理寫的,現(xiàn)在大家對普通構(gòu)造函數(shù),拷貝構(gòu)造函數(shù),賦值函數(shù)的區(qū)別和實現(xiàn)應(yīng)該都清楚了。

以上所述是小編給大家介紹的C++中構(gòu)造函數(shù),拷貝構(gòu)造函數(shù)和賦值函數(shù)的區(qū)別和實現(xiàn)詳解整合,希望對大家有所幫助,如果大家有任何疑問請給我留言,小編會及時回復(fù)大家的。在此也非常感謝大家對腳本之家網(wǎng)站的支持!

相關(guān)文章

  • C++ Boost Pool超詳細(xì)講解

    C++ Boost Pool超詳細(xì)講解

    Boost是為C++語言標(biāo)準(zhǔn)庫提供擴(kuò)展的一些C++程序庫的總稱。Boost庫是一個可移植、提供源代碼的C++庫,作為標(biāo)準(zhǔn)庫的后備,是C++標(biāo)準(zhǔn)化進(jìn)程的開發(fā)引擎之一,是為C++語言標(biāo)準(zhǔn)庫提供擴(kuò)展的一些C++程序庫的總稱
    2022-11-11
  • c++實現(xiàn)值機系統(tǒng)

    c++實現(xiàn)值機系統(tǒng)

    這篇文章主要為大家詳細(xì)介紹了c++實現(xiàn)在線值機系統(tǒng)程序,文中示例代碼介紹的非常詳細(xì),具有一定的參考價值,感興趣的小伙伴們可以參考一下
    2022-03-03
  • 對C++默認(rèn)構(gòu)造函數(shù)的一點重要說明

    對C++默認(rèn)構(gòu)造函數(shù)的一點重要說明

    下面小編就為大家?guī)硪黄獙++默認(rèn)構(gòu)造函數(shù)的一點重要說明。小編覺得挺不錯的,現(xiàn)在就分享給大家,也給大家做個參考。一起跟隨小編過來看看吧
    2016-12-12
  • 詳解在VScode中添加代碼塊(含C++指令生成代碼)

    詳解在VScode中添加代碼塊(含C++指令生成代碼)

    這篇文章主要介紹了詳解在VScode中添加代碼塊(含C++指令生成代碼),文中通過示例代碼介紹的非常詳細(xì),對大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價值,需要的朋友們下面隨著小編來一起學(xué)習(xí)學(xué)習(xí)吧
    2021-04-04
  • VC6實現(xiàn)激活后臺窗口最佳方法

    VC6實現(xiàn)激活后臺窗口最佳方法

    這篇文章主要介紹了VC6實現(xiàn)激活后臺窗口最佳方法,實例分析了VC操作后臺窗口的技巧,需要的朋友可以參考下
    2015-06-06
  • C++實現(xiàn)圖的鄰接矩陣表示

    C++實現(xiàn)圖的鄰接矩陣表示

    這篇文章主要為大家詳細(xì)介紹了C++實現(xiàn)圖的鄰接矩陣表示,文中示例代碼介紹的非常詳細(xì),具有一定的參考價值,感興趣的小伙伴們可以參考一下
    2020-04-04
  • OpenCV4 實現(xiàn)背景分離的詳細(xì)步驟(背景減法模型)

    OpenCV4 實現(xiàn)背景分離的詳細(xì)步驟(背景減法模型)

    背景分離(BS)是一種通過使用靜態(tài)相機來生成前景掩碼(即包含屬于場景中的移動對象像素的二進(jìn)制圖像)的常用技術(shù),本文給大家介紹OpenCV4 實現(xiàn)背景分離的詳細(xì)步驟,需要的朋友可以參考下
    2021-09-09
  • QML中動態(tài)與靜態(tài)模型應(yīng)用詳解

    QML中動態(tài)與靜態(tài)模型應(yīng)用詳解

    QML是一種描述性的腳本語言,文件格式以.qml結(jié)尾。語法格式非常像CSS(參考后文具體例子),但又支持javascript形式的編程控制。QtDesigner可以設(shè)計出·ui界面文件,但是不支持和Qt原生C++代碼的交互
    2022-08-08
  • Mac下使用Eclipse編譯C/C++文件出現(xiàn) launch failed, binary not found 解決方案

    Mac下使用Eclipse編譯C/C++文件出現(xiàn) launch failed, binary not found 解決方

    這篇文章主要介紹了Mac下使用Eclipse編譯C/C++文件出現(xiàn) launch failed, binary not found 解決方案,需要的朋友可以參考下
    2014-10-10
  • OpenGL實現(xiàn)鼠標(biāo)移動方塊

    OpenGL實現(xiàn)鼠標(biāo)移動方塊

    這篇文章主要為大家詳細(xì)介紹了OpenGL實現(xiàn)鼠標(biāo)移動方塊,文中示例代碼介紹的非常詳細(xì),具有一定的參考價值,感興趣的小伙伴們可以參考一下
    2020-08-08

最新評論

沈阳市| 资兴市| 左权县| 泰来县| 荣成市| 明光市| 正镶白旗| 宜川县| 年辖:市辖区| 天长市| 富川| 清丰县| 定襄县| 武陟县| 桓仁| 剑阁县| 赣榆县| 镇雄县| 玉溪市| 大石桥市| 淮阳县| 来宾市| 台中县| 瓮安县| 庄河市| 东乡| 恭城| 昂仁县| 武宣县| 北票市| 虎林市| 江源县| 河曲县| 安多县| 沂源县| 佛冈县| 黔南| 沾益县| 菏泽市| 普安县| 和平区|