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

詳解C++ 拷貝構(gòu)造函數(shù)

 更新時間:2020年07月09日 11:36:54   作者:菜鳥教程  
這篇文章主要介紹了C++ 拷貝構(gòu)造函數(shù)的相關(guān)資料,文中示例代碼非常詳細,幫助大家更好的理解和學習,感興趣的朋友可以了解下

拷貝構(gòu)造函數(shù)是一種特殊的構(gòu)造函數(shù),它在創(chuàng)建對象時,是使用同一類中之前創(chuàng)建的對象來初始化新創(chuàng)建的對象??截悩?gòu)造函數(shù)通常用于:

  • 通過使用另一個同類型的對象來初始化新創(chuàng)建的對象。
  • 復制對象把它作為參數(shù)傳遞給函數(shù)。
  • 復制對象,并從函數(shù)返回這個對象。

如果在類中沒有定義拷貝構(gòu)造函數(shù),編譯器會自行定義一個。如果類帶有指針變量,并有動態(tài)內(nèi)存分配,則它必須有一個拷貝構(gòu)造函數(shù)??截悩?gòu)造函數(shù)的最常見形式如下:

classname (const classname &obj) {
  // 構(gòu)造函數(shù)的主體
}

在這里,obj 是一個對象引用,該對象是用于初始化另一個對象的。

#include <iostream>
 
using namespace std;
 
class Line
{
  public:
   int getLength( void );
   Line( int len );       // 簡單的構(gòu)造函數(shù)
   Line( const Line &obj);   // 拷貝構(gòu)造函數(shù)
   ~Line();           // 析構(gòu)函數(shù)
 
  private:
   int *ptr;
};
 
// 成員函數(shù)定義,包括構(gòu)造函數(shù)
Line::Line(int len)
{
  cout << "調(diào)用構(gòu)造函數(shù)" << endl;
  // 為指針分配內(nèi)存
  ptr = new int;
  *ptr = len;
}
 
Line::Line(const Line &obj)
{
  cout << "調(diào)用拷貝構(gòu)造函數(shù)并為指針 ptr 分配內(nèi)存" << endl;
  ptr = new int;
  *ptr = *obj.ptr; // 拷貝值
}
 
Line::~Line(void)
{
  cout << "釋放內(nèi)存" << endl;
  delete ptr;
}
int Line::getLength( void )
{
  return *ptr;
}
 
void display(Line obj)
{
  cout << "line 大小 : " << obj.getLength() <<endl;
}
 
// 程序的主函數(shù)
int main( )
{
  Line line(10);
 
  display(line);
 
  return 0;
}

當上面的代碼被編譯和執(zhí)行時,它會產(chǎn)生下列結(jié)果:

調(diào)用構(gòu)造函數(shù)
調(diào)用拷貝構(gòu)造函數(shù)并為指針 ptr 分配內(nèi)存
line 大小 : 10
釋放內(nèi)存
釋放內(nèi)存

下面的實例對上面的實例稍作修改,通過使用已有的同類型的對象來初始化新創(chuàng)建的對象:

#include <iostream>
 
using namespace std;
 
class Line
{
  public:
   int getLength( void );
   Line( int len );       // 簡單的構(gòu)造函數(shù)
   Line( const Line &obj);   // 拷貝構(gòu)造函數(shù)
   ~Line();           // 析構(gòu)函數(shù)
 
  private:
   int *ptr;
};
 
// 成員函數(shù)定義,包括構(gòu)造函數(shù)
Line::Line(int len)
{
  cout << "調(diào)用構(gòu)造函數(shù)" << endl;
  // 為指針分配內(nèi)存
  ptr = new int;
  *ptr = len;
}
 
Line::Line(const Line &obj)
{
  cout << "調(diào)用拷貝構(gòu)造函數(shù)并為指針 ptr 分配內(nèi)存" << endl;
  ptr = new int;
  *ptr = *obj.ptr; // 拷貝值
}
 
Line::~Line(void)
{
  cout << "釋放內(nèi)存" << endl;
  delete ptr;
}
int Line::getLength( void )
{
  return *ptr;
}
 
void display(Line obj)
{
  cout << "line 大小 : " << obj.getLength() <<endl;
}
 
// 程序的主函數(shù)
int main( )
{
  Line line1(10);
 
  Line line2 = line1; // 這里也調(diào)用了拷貝構(gòu)造函數(shù)
 
  display(line1);
  display(line2);
 
  return 0;
}

當上面的代碼被編譯和執(zhí)行時,它會產(chǎn)生下列結(jié)果:

調(diào)用構(gòu)造函數(shù)
調(diào)用拷貝構(gòu)造函數(shù)并為指針 ptr 分配內(nèi)存
調(diào)用拷貝構(gòu)造函數(shù)并為指針 ptr 分配內(nèi)存
line 大小 : 10
釋放內(nèi)存
調(diào)用拷貝構(gòu)造函數(shù)并為指針 ptr 分配內(nèi)存
line 大小 : 10
釋放內(nèi)存
釋放內(nèi)存
釋放內(nèi)存

關(guān)于為什么當類成員中含有指針類型成員且需要對其分配內(nèi)存時,一定要有總定義拷貝構(gòu)造函數(shù)??

默認的拷貝構(gòu)造函數(shù)實現(xiàn)的只能是淺拷貝,即直接將原對象的數(shù)據(jù)成員值依次復制給新對象中對應的數(shù)據(jù)成員,并沒有為新對象另外分配內(nèi)存資源。

這樣,如果對象的數(shù)據(jù)成員是指針,兩個指針對象實際上指向的是同一塊內(nèi)存空間。

在某些情況下,淺拷貝回帶來數(shù)據(jù)安全方面的隱患。

當類的數(shù)據(jù)成員中有指針類型時,我們就必須定義一個特定的拷貝構(gòu)造函數(shù),該拷貝構(gòu)造函數(shù)不僅可以實現(xiàn)原對象和新對象之間數(shù)據(jù)成員的拷貝,而且可以為新的對象分配單獨的內(nèi)存資源,這就是深拷貝構(gòu)造函數(shù)。

如何防止默認拷貝發(fā)生

聲明一個私有的拷貝構(gòu)造函數(shù),這樣因為拷貝構(gòu)造函數(shù)是私有的,如果用戶試圖按值傳遞或函數(shù)返回該類的對象,編譯器會報告錯誤,從而可以避免按值傳遞或返回對象。

總結(jié):

當出現(xiàn)類的等號賦值時,會調(diào)用拷貝函數(shù),在未定義顯示拷貝構(gòu)造函數(shù)的情況下,系統(tǒng)會調(diào)用默認的拷貝函數(shù)——即淺拷貝,它能夠完成成員的一一復制。當數(shù)據(jù)成員中沒有指針時,淺拷貝是可行的。但當數(shù)據(jù)成員中有指針時,如果采用簡單的淺拷貝,則兩類中的兩個指針將指向同一個地址,當對象快結(jié)束時,會調(diào)用兩次析構(gòu)函數(shù),而導致指針懸掛現(xiàn)象。所以,這時,必須采用深拷貝。

深拷貝與淺拷貝的區(qū)別就在于深拷貝會在堆內(nèi)存中另外申請空間來儲存數(shù)據(jù),從而也就解決了指針懸掛的問題。簡而言之,當數(shù)據(jù)成員中有指針時,必須要用深拷貝。

以上就是詳解C++ 拷貝構(gòu)造函數(shù)的詳細內(nèi)容,更多關(guān)于C++ 拷貝構(gòu)造函數(shù)的資料請關(guān)注腳本之家其它相關(guān)文章!

相關(guān)文章

  • C++之多態(tài)(內(nèi)容不錯)

    C++之多態(tài)(內(nèi)容不錯)

    什么是多態(tài)?顧名思義就是同一個事物在不同場景下的多種形態(tài),需要的朋友可以參考下
    2020-01-01
  • VC++實現(xiàn)添加文件關(guān)聯(lián)的方法示例

    VC++實現(xiàn)添加文件關(guān)聯(lián)的方法示例

    這篇文章主要介紹了VC++實現(xiàn)添加文件關(guān)聯(lián)的方法,涉及VC++針對注冊表的寫入與VC事件響應相關(guān)操作技巧,需要的朋友可以參考下
    2017-08-08
  • VSCode 配置C++開發(fā)環(huán)境的方法步驟

    VSCode 配置C++開發(fā)環(huán)境的方法步驟

    這篇文章主要介紹了VSCode 配置C++開發(fā)環(huán)境的方法步驟,文中通過示例代碼介紹的非常詳細,對大家的學習或者工作具有一定的參考學習價值,需要的朋友們下面隨著小編來一起學習學習吧
    2020-03-03
  • C++中的數(shù)據(jù)內(nèi)存分布原理

    C++中的數(shù)據(jù)內(nèi)存分布原理

    這篇文章主要介紹了C++中的數(shù)據(jù)內(nèi)存分布,主要從動態(tài)內(nèi)存管理方式,內(nèi)存泄漏等方面介紹的,文中也有相關(guān)的示例代碼,需要的朋友可以參考下
    2023-05-05
  • C++ 超詳細快速掌握二叉搜索樹

    C++ 超詳細快速掌握二叉搜索樹

    從這篇博客開始,我就要和大家介紹有關(guān)二叉搜索樹的知識,它還衍生出了兩棵樹——AVL樹和紅黑樹,在后面兩篇博客我都會介紹。今天先從二叉搜索樹開始引入
    2022-03-03
  • C++ 頭文件系列(set)詳解

    C++ 頭文件系列(set)詳解

    一般而言,每個C++/C程序通常由頭文件和定義文件組成。頭文件作為一種包含功能函數(shù)、數(shù)據(jù)接口聲明的載體文件,主要用于保存程序的聲明,而定義文件用于保存程序的實現(xiàn) 。
    2017-02-02
  • C語言輕松實現(xiàn)掃雷小游戲

    C語言輕松實現(xiàn)掃雷小游戲

    掃雷是一款經(jīng)典的小游戲,這篇文章主要為大家詳細介紹了C語言輕松實現(xiàn)掃雷小游戲,文中示例代碼介紹的非常詳細,具有一定的參考價值,感興趣的小伙伴們可以參考一下
    2022-08-08
  • 給C語言初學者的學習建議

    給C語言初學者的學習建議

    在本篇文章里小編給大家分享的是關(guān)于C語言學習建議的相關(guān)內(nèi)容,有興趣的朋友們可以學習參考下。
    2020-06-06
  • 你真的懂C++中的namespace用法

    你真的懂C++中的namespace用法

    命名空間(namespace)為防止名字沖突提供了更加可控的機制,命名空間分割了全局命名空間,其中每個命名空間是一個作用域,今天通過本文給大家分享C++中namespace用法,感興趣的朋友一起看看吧
    2021-06-06
  • C語言實現(xiàn)簡單掃雷小程序

    C語言實現(xiàn)簡單掃雷小程序

    這篇文章主要為大家詳細介紹了C語言實現(xiàn)簡單掃雷小程序,一款大眾類的益智小游戲,文中示例代碼介紹的非常詳細,具有一定的參考價值,感興趣的小伙伴們可以參考一下
    2019-10-10

最新評論

商都县| 康平县| 仁布县| 禄丰县| 特克斯县| 年辖:市辖区| 郑州市| 易门县| 来宾市| 温宿县| 密山市| 策勒县| 黑山县| 漠河县| 临沧市| 贡山| 涞水县| 璧山县| 永新县| 高雄市| 行唐县| 民权县| 苍南县| 西畴县| 桂东县| 绥芬河市| 麻栗坡县| 嘉祥县| 绥滨县| 周口市| 陈巴尔虎旗| 甘德县| 资阳市| 泰兴市| 桐梓县| 曲周县| 镇雄县| 昌都县| 宜阳县| 上犹县| 秦安县|