青青草原综合久久大伊人导航_色综合久久天天综合_日日噜噜夜夜狠狠久久丁香五月_热久久这里只有精品

woaidongmao

文章均收錄自他人博客,但不喜標題前加-[轉貼],因其丑陋,見諒!~
隨筆 - 1469, 文章 - 0, 評論 - 661, 引用 - 0
數據加載中……

拷貝構造函數

  拷貝構造函數,是一種特殊的構造函數,它由編譯器調用來完成一些基于同一類的其他對象的構建及初始化。其唯一的參數(對象的引用)是不可變的(const類型)。此函數經常用在函數調用時用戶定義類型的值傳遞及返回。拷貝構造函數要調用基類的拷貝構造函數和成員函數。如果可以的話,它將用常量方式調用,另外,也可以用非常量方式調用。

  在C++中,下面三種對象需要調用拷貝構造函數:

  1) 一個對象以值傳遞的方式傳入函數體;

  2) 一個對象以值傳遞的方式從函數返回;

  3) 一個對象需要通過另外一個對象進行初始化;

  如果在前兩種情況不使用拷貝構造函數的時候,就會導致一個指針指向已經被刪除的內存空間。對于第三種情況來說,初始化和賦值的不同含義是構造函數調用的原因。事實上,拷貝構造函數是由普通構造函數和賦值操作符共同實現的。描述拷貝構造函數和賦值運算符的異同的參考資料有很多。

  拷貝構造函數不可以改變它所引用的對象,其原因如下:當一個對象以傳遞值的方式傳一個函數的時候,拷貝構造函數自動的被調用來生成函數中的對象。如果一個對象是被傳入自己的拷貝構造函數,它的拷貝構造函數將會被調用來拷貝這個對象這樣復制才可以傳入它自己的拷貝構造函數,這會導致無限循環直至棧溢出(Stack Overflow)。除了當對象傳入函數的時候被隱式調用以外,拷貝構造函數在對象被函數返回的時候也同樣的被調用。

  如果在類中沒有顯式的聲明一個拷貝構造函數,那么,編譯器會自動生成一個來進行對象之間的位拷貝(Bitwise Copy)。這個隱含的拷貝構造函數簡單的關聯了所有的類成員。注意到這個隱式的拷貝構造函數和顯式聲明的拷貝構造函數的不同在于對成員的關聯方式。顯式聲明的拷貝構造函數關聯的只是被實例化的類成員的缺省構造函數,除非另外一個構造函數在類初始化或構造列表的時候被調用。

  拷貝構造函數使程序更有效率,因為它不用再構造一個對象的時候改變構造函數的參數列表。設計拷貝構造函數是一個良好的風格,即使是編譯系統會自動為你生成默認拷貝構造函數。事實上,默認拷貝構造函數可以應付許多情況。

  以下討論中將用到的例子:

  class CExample

  {

  public:

  CExample(){pBuffer=NULL; nSize=0;}

  ~CExample(){delete pBuffer;}

  void Init(int n){ pBuffer=new char[n]; nSize=n;}

  private:

  char *pBuffer; //類的對象中包含指針,指向動態分配的內存資源

  int nSize;

  };

  這個類的主要特點是包含指向其他資源的指針。

  pBuffer指向堆中分配的一段內存空間。

  一、拷貝構造函數

  int main(int argc, char* argv[])

  {

  CExample theObjone;

  theObjone.Init(40);

  //現在需要另一個對象,需要將他初始化稱對象一的狀態

  CExample theObjtwo=theObjone;

  ...

  }

  語句"CExample theObjtwo=theObjone;"theObjone初始化theObjtwo

  其完成方式是內存拷貝,復制所有成員的值。

  完成后,theObjtwo.pBuffer==theObjone.pBuffer

  即它們將指向同樣的地方,指針雖然復制了,但所指向的空間并沒有復制,而是由兩個對象共用了。這樣不符合要求,對象之間不獨立了,并為空間的刪除帶來隱患。所以需要采用必要的手段來避免此類情況。

  回顧以下此語句的具體過程:首先建立對象theObjtwo,并調用其構造函數,然后成員被拷貝。

  可以在構造函數中添加操作來解決指針成員的問題。

  所以C++語法中除了提供缺省形式的構造函數外,還規范了另一種特殊的構造函數:拷貝構造函數,上面的語句中,如果類中定義了拷貝構造函數,這對象建立時,調用的將是拷貝構造函數,在拷貝構造函數中,可以根據傳入的變量,復制指針所指向的資源。

  拷貝構造函數的格式為:構造函數名(對象的引用)

  提供了拷貝構造函數后的CExample類定義為:

  class CExample

  {

  public:

  CExample(){pBuffer=NULL; nSize=0;}

  ~CExample(){delete pBuffer;}

  CExample(const CExample&); //拷貝構造函數

  void Init(int n){ pBuffer=new char[n]; nSize=n;}

  private:

  char *pBuffer; //類的對象中包含指針,指向動態分配的內存資源

  int nSize;

  };

  CExample::CExample(const CExample& RightSides) //拷貝構造函數的定義

  {

  nSize=RightSides.nSize; //復制常規成員

  pBuffer=new char[nSize]; //復制指針指向的內容

  memcpy(pBuffer,RightSides.pBuffer,nSize*sizeof(char));

  }

  這樣,定義新對象,并用已有對象初始化新對象時,CExample(const CExample& RightSides)將被調用,而已有對象用別名RightSides傳給構造函數,以用來作復制。原則上,應該為所有包含動態分配成員的類都提供拷貝構造函數。

  下面介紹拷貝構造函數的另一種調用。當對象直接作為參數傳給函數時,函數將建立對象的臨時拷貝,這個拷貝過程也將調同拷貝構造函數。例如:

  BOOL testfunc(CExample obj);

  testfunc(theObjone); //對象直接作為參數。

  BOOL testfunc(CExample obj)

  {

  //針對obj的操作實際上是針對復制后的臨時拷貝進行的

  }

  還有一種情況,也是與臨時對象有關的

  當函數中的局部對象被被返回給函數調者時,也將建立此局部對象的一個臨時拷貝,拷貝構造函數也將被調用

  CTest func()

  {

  CTest theTest;

  return theTest;

  }

  二、賦值符的重載

  下面的代碼與上例相似

  int main(int argc, char* argv[])

  {

  CExample theObjone;

  theObjone.Init(40);

  CExample theObjthree;

  theObjthree.Init(60);

  //現在需要一個對象賦值操作,被賦值對象的原內容被清除,并用右邊對象的內容填充。

  theObjthree=theObjone;

  return 0;

  }

  也用到了"="號,但與"一、"中的例子并不同,"一、"的例子中,"="在對象聲明語句中,表示初始化。更多時候,這種初始化也可用括號表示。

  例如 CExample theObjone(theObjtwo);

  而本例子中,"="表示賦值操作。將對象theObjone的內容復制到對象theObjthree;,這其中涉及到對象theObjthree原有內容的丟棄,新內容的復制。

  但"="的缺省操作只是將成員變量的值相應復制。舊的值被自然丟棄。

  由于對象內包含指針,將造成不良后果:指針的值被丟棄了,但指針指向的內容并未釋放。指針的值被復制了,但指針所指內容并未復制。

  因此,包含動態分配成員的類除提供拷貝構造函數外,還應該考慮重載"="賦值操作符號。

  類定義變為:

  class CExample

  {

  ...

  CExample(const CExample&); //拷貝構造函數

  CExample& operator = (const CExample&); //賦值符重載

  ...

  };

  //賦值操作符重載

  CExample & CExample::operator = (const CExample& RightSides)

  {

  nSize=RightSides.nSize; //復制常規成員

  char *temp=new char[nSize]; //復制指針指向的內容

  memcpy(temp,RightSides.pBuffer,nSize*sizeof(char));

  delete []pBuffer; //刪除原指針指向內容 (將刪除操作放在后面,避免X=X特殊情況下,內容的丟失)

  pBuffer=NULL;

  pBuffer=temp; //建立新指向

  return *this

  }

  三、注意事項

  常見錯誤:

  拷貝構造函數使用賦值運算符重載的代碼。

  CExample::CExample(const CExample& RightSides)

  {

  *this=RightSides //調用重載后的"="

  }

  而這樣會造成循環調用重載后的"="和拷貝構造函數,最后造成棧溢出(Stack Overflow)

  四,拷貝構造函數與構造函數的區別

  class 類名

  {

  public

  類名(形參參數)//構造函數

  類名(類名&對象名)//拷貝構造函數

  ,,,,,,,,,,,,,,,,,,,,,

  };

  拷貝構造函數的實現:

  類名::類名(類名&對象名)//拷貝構造函數的實現

  {函數體}

  不完整的例子

  拷貝構造函數:

  Class Point

  {

  Public:

  Point(int xx=0,int yy=m)(X=xx;Y=yy;)

  Point(Point& p);

  Int getX() {return X}

  Int getY(){ return Y;}

  Private :

  Int X,Y;

  }

  Point::Point(Point& p)

  {

  X=p.X;

  Y=p.Y;

  Cout<<"拷貝構造函數吊樣"<<endl;

  }

posted on 2009-01-22 12:18 肥仔 閱讀(589) 評論(0)  編輯 收藏 引用 所屬分類: C++ 基礎

青青草原综合久久大伊人导航_色综合久久天天综合_日日噜噜夜夜狠狠久久丁香五月_热久久这里只有精品
  • <ins id="pjuwb"></ins>
    <blockquote id="pjuwb"><pre id="pjuwb"></pre></blockquote>
    <noscript id="pjuwb"></noscript>
          <sup id="pjuwb"><pre id="pjuwb"></pre></sup>
            <dd id="pjuwb"></dd>
            <abbr id="pjuwb"></abbr>
            国产精一区二区三区| 在线性视频日韩欧美| 99在线精品视频| 亚洲影视九九影院在线观看| 亚洲一区二区三区中文字幕在线| 中文av一区二区| 欧美在线免费看| 麻豆精品视频在线观看| 欧美黄网免费在线观看| 99国产精品视频免费观看| 亚洲综合色激情五月| 久久成人人人人精品欧| 免费视频一区二区三区在线观看| 欧美精品1区2区| 国产精品实拍| 亚洲国产一区二区三区高清| 亚洲天堂男人| 欧美成人a视频| 中国女人久久久| 久久精品二区亚洲w码| 欧美激情一区在线| 国产精品美女久久久久久2018 | 亚洲欧美日本精品| 久久裸体艺术| 日韩午夜电影在线观看| 亚洲欧美在线一区二区| 你懂的国产精品| 国产精自产拍久久久久久| 亚洲国产三级| 欧美在线播放一区| 欧美激情视频给我| 亚洲综合欧美日韩| 欧美精品在线网站| 玉米视频成人免费看| 午夜精品久久久久久久久久久久久 | 欧美成人xxx| 国产精品xnxxcom| 欧美在线www| 欧美日韩大片一区二区三区| 狠狠色噜噜狠狠狠狠色吗综合| 一区二区三区精品国产| 美女精品国产| 亚洲欧美中文日韩在线| 欧美精品一区二区三| 国语自产精品视频在线看| 午夜性色一区二区三区免费视频 | 一本久道综合久久精品| 老司机免费视频一区二区| 国产一区二区久久精品| 欧美一区2区三区4区公司二百 | 午夜亚洲福利在线老司机| 亚洲人午夜精品| 久久久噜噜噜久久中文字幕色伊伊| 国产精品a级| 中文亚洲欧美| 亚洲欧洲一区二区三区在线观看| 老巨人导航500精品| 一色屋精品亚洲香蕉网站| 欧美亚洲一区二区三区| 一区二区三区精品久久久| 欧美日韩亚洲成人| 亚洲九九精品| 日韩视频中文| 国产精品三级视频| 久久久久国产精品www| 久久国产精品久久精品国产| 国产在线乱码一区二区三区| 久久精品国产免费看久久精品| 亚洲自拍偷拍色片视频| 国产精品久久网站| 欧美一区视频| 久久亚洲欧美| 亚洲精品亚洲人成人网| 亚洲国产成人精品久久| 欧美精品啪啪| 亚洲欧美日韩成人高清在线一区| 亚洲少妇自拍| 狠色狠色综合久久| 欧美激情视频一区二区三区不卡| 欧美大片第1页| 亚洲深夜福利网站| 欧美伊人久久久久久久久影院| 国产一区二区在线观看免费播放 | 91久久国产综合久久蜜月精品 | 欧美不卡视频一区发布| 欧美激情四色| 亚洲午夜精品视频| 久久久久久久久久久久久久一区 | 欧美电影在线观看| 欧美激情综合五月色丁香| 国产精品99久久久久久久女警 | 欧美另类人妖| 亚洲在线免费视频| 午夜久久影院| 亚洲人成网站777色婷婷| 日韩一区二区久久| 国产一区二区三区最好精华液| 欧美成人一区二区| 国产精品第13页| 欧美伦理视频网站| 久久精品中文字幕免费mv| 欧美成人在线免费观看| 小黄鸭精品aⅴ导航网站入口 | 午夜精品久久久久久99热软件| 久久久久久尹人网香蕉| 在线中文字幕日韩| 久久深夜福利免费观看| 亚洲在线观看视频| 欧美成人第一页| 久久久xxx| 国产精品美女久久久| 亚洲精品国产精品久久清纯直播| 国产一区二区三区直播精品电影| 99re这里只有精品6| 亚洲电影免费观看高清| 午夜日韩电影| 午夜激情综合网| 欧美经典一区二区三区| 欧美国产欧美综合 | 一区二区不卡在线视频 午夜欧美不卡' | 欧美少妇一区| 欧美国产一区在线| 国产亚洲美州欧州综合国| 正在播放欧美视频| 一区二区精品国产| 欧美护士18xxxxhd| 欧美成人免费全部| 在线日韩视频| 久久精品亚洲一区二区| 久久精品三级| 国产一区深夜福利| 欧美一区二区视频97| 欧美亚洲在线观看| 国产精品久久夜| 亚洲午夜国产一区99re久久| 日韩一级片网址| 亚洲精品一区二区三| 日韩网站在线看片你懂的| 久久在线观看视频| 免费91麻豆精品国产自产在线观看| 国产精品分类| 国产精品久久97| 一本色道**综合亚洲精品蜜桃冫| 亚洲最新视频在线播放| 欧美日韩高清在线| 亚洲美女一区| 亚洲一区二区三区四区视频| 欧美亚男人的天堂| 亚洲欧美卡通另类91av| 国产欧美亚洲日本| 午夜精品成人在线| 久久综合五月| 在线日韩欧美| 欧美激情无毛| 亚洲欧美日韩在线高清直播| 久久久久国产精品麻豆ai换脸| 永久久久久久| 欧美激情亚洲另类| 中日韩美女免费视频网址在线观看 | 欧美中文在线免费| 韩日视频一区| 欧美国内亚洲| 亚洲婷婷免费| 久久亚洲国产成人| 亚洲精品一区在线观看香蕉| 欧美体内she精视频| 午夜精品福利一区二区蜜股av| 久久精品国产一区二区三| 亚洲国产精品高清久久久| 欧美日韩另类视频| 久久国产精品亚洲77777| 亚洲欧洲精品一区二区三区不卡| 亚洲欧美日韩在线综合| 伊人久久av导航| 国产精品jvid在线观看蜜臀| 欧美自拍偷拍午夜视频| 亚洲国产精品久久久久久女王| 亚洲免费视频一区二区| 亚洲成色999久久网站| 国产精品久久久久aaaa| 久久久久网站| 亚洲自拍偷拍色片视频| 亚洲国产福利在线| 久久久av毛片精品| 亚洲小视频在线| 亚洲精品麻豆| 国内不卡一区二区三区| 欧美日韩一卡| 免播放器亚洲一区| 欧美一级片在线播放| 亚洲精品社区| 欧美大片91| 久久理论片午夜琪琪电影网| 一区二区免费看| 在线免费不卡视频| 国产一区91| 国产免费成人av| 欧美小视频在线观看| 欧美国产日韩a欧美在线观看| 欧美与黑人午夜性猛交久久久|