久久久久久久999_99精品久久精品一区二区爱城_成人欧美一区二区三区在线播放_国产精品日本一区二区不卡视频_国产午夜视频_欧美精品在线观看免费

 找回密碼
 立即注冊

QQ登錄

只需一步,快速開始

搜索
查看: 1737|回復: 0
收起左側

拷貝構造函數和賦值構造函數聲明為私有的作用

[復制鏈接]
ID:107189 發表于 2016-3-6 02:07 | 顯示全部樓層 |閱讀模式
每個類只有一個賦值函數.

  由于并非所有的對象都會使用拷貝構造函數和賦值函數,程序員可能對這兩個函數有些輕視。請先記住以下的警告,在閱讀正文時就會多心:
  1.如果不主動編寫拷貝構造函數和賦值函數,編譯器將以“位拷貝”的方式自動生成缺省的函數。倘若類中含有指針變量,那么這兩個缺省的函數就隱含了錯誤。以類String的兩個對象a,b為例,假設a.m_data的內容為“hello”,b.m_data的內容為“world”。
  現將a賦給b,缺省賦值函數的“位拷貝”意味著執行b.m_data = a.m_data。這將造成三個錯誤:一是b.m_data原有的內存沒被釋放,造成內存泄露;二是b.m_data和a.m_data指向同一塊內存,a或b任何一方變動都會影響另一方;三是在對象被析構時,m_data被釋放了兩次。
  2.拷貝構造函數和賦值函數非常容易混淆,常導致錯寫、錯用。拷貝構造函數是在對象被創建時調用的,而賦值函數只能被已經存在了的對象調用。以下程序中,第三個語句和第四個語句很相似,你分得清楚哪個調用了拷貝構造函數,哪個調用了賦值函數嗎?
  String a(“hello”);
  String b(“world”);
  String c = a; // 調用了拷貝構造函數,最好寫成 c(a);
  c = b; // 調用了賦值函數
  本例中第三個語句的風格較差,宜改寫成String c(a) 以區別于第四個語句。
  類String的拷貝構造函數與賦值函數
  // 拷貝構造函數
  String::String(const String &other)
  {
  // 允許操作other的私有成員m_data
  int length = strlen(other.m_data);
  m_data = new char[length+1];
  strcpy(m_data, other.m_data);
  }
  // 賦值函數
  String & String::operate =(const String &other)
  {
  // (1) 檢查自賦值
  if(this == &other)
  return *this;
  // (2) 釋放原有的內存資源
  delete [] m_data;
  // (3)分配新的內存資源,并復制內容
  int length = strlen(other.m_data);
  m_data = new char[length+1];
  strcpy(m_data, other.m_data);
  // (4)返回本對象的引用
  return *this;
  }
  類String拷貝構造函數與普通構造函數的區別是:在函數入口處無需與NULL進行比較,這是因為“引用”不可能是NULL,而“指針”可以為NULL。
  類String的賦值函數比構造函數復雜得多,分四步實現:
  (1)第一步,檢查自賦值。你可能會認為多此一舉,難道有人會愚蠢到寫出 a = a 這樣的自賦值語句!的確不會。但是間接的自賦值仍有可能出現,例如
  // 內容自賦值
  b = a;
  …
  c = b;
  …
  a = c;
  // 地址自賦值
  b = &a;
  …
  a = *b;
  也許有人會說:“即使出現自賦值,我也可以不理睬,大不了化點時間讓對象復制自己而已,反正不會出錯!”
  他真的說錯了。看看第二步的delete,自殺后還能復制自己嗎?所以,如果發現自賦值,應該馬上終止函數。注意不要將檢查自賦值的if語句
  if(this == &other)
  錯寫成為
  if( *this == other)
  (2)第二步,用delete釋放原有的內存資源。如果現在不釋放,以后就沒機會了,將造成內存泄露。
  (3)第三步,分配新的內存資源,并復制字符串。注意函數strlen返回的是有效字符串長度,不包含結束符‘\0’。函數strcpy則連‘\0’一起復制。
  (4)第四步,返回本對象的引用,目的是為了實現象 a = b = c 這樣的鏈式表達。注意不要將 return *this 錯寫成 return this 。那么能否寫成return other 呢?效果不是一樣嗎?
  不可以!因為我們不知道參數other的生命期。有可能other是個臨時對象,在賦值結束后它馬上消失,那么return other返回的將是垃圾。
  偷懶的辦法處理拷貝構造函數與賦值函數

  如果我們實在不想編寫拷貝構造函數和賦值函數,又不允許別人使用編譯器生成的缺省函數,怎么辦?

  偷懶的辦法是:只需將拷貝構造函數和賦值函數聲明為私有函數,不用編寫代碼。

  例如:
  class A
  { …
  private:
  A(const A &a); // 私有的拷貝構造函數
  A & operate =(const A &a); // 私有的賦值函數
  };
  如果有人試圖編寫如下程序:
  A b(a); // 調用了私有的拷貝構造函數
  b = a; // 調用了私有的賦值函數
  編譯器將指出錯誤,因為外界不可以操作A的私有函數。
  3.在編寫派生類的賦值函數時,注意不要忘記對基類的數據成員重新賦值.

回復

使用道具 舉報

您需要登錄后才可以回帖 登錄 | 立即注冊

本版積分規則

小黑屋|51黑電子論壇 |51黑電子論壇6群 QQ 管理員QQ:125739409;技術交流QQ群281945664

Powered by 單片機教程網

快速回復 返回頂部 返回列表
主站蜘蛛池模板: 国产精品美女久久久久aⅴ国产馆 | 亚洲美女一区二区三区 | 午夜视频在线观看网站 | 久久国产精品免费 | 色视频成人在线观看免 | 成人欧美一区二区三区在线播放 | 色久电影 | 久久一区二区三区四区 | 国产欧美一区二区在线观看 | 国产一区二区在线免费观看 | 天色综合网 | 中文字幕精品一区 | 1000部精品久久久久久久久 | 日韩一区二区三区视频 | 99爱国产 | 在线a视频 | 日韩免费| 久久人人网 | 精品欧美一区二区中文字幕视频 | 久草在线在线精品观看 | 日韩精品人成在线播放 | 91 在线 | 欧美日韩久久精品 | 日韩精品1区2区3区 成人黄页在线观看 | 日韩精品一区二区三区中文字幕 | 日本在线视 | 国产资源视频 | 国产成人99久久亚洲综合精品 | 亚洲精品一区二区网址 | 久久久国产精品入口麻豆 | 人人干人人看 | 91精品国产一区二区三区 | 91在线看视频 | 久久久成人精品 | 日韩免费一区二区 | 国产精品资源在线观看 | 日韩欧美天堂 | 午夜伦理影院 | h视频免费在线观看 | 中文字幕91 | 日韩靠逼|