91超碰碰碰碰久久久久久综合_超碰av人澡人澡人澡人澡人掠_国产黄大片在线观看画质优化_txt小说免费全本

溫馨提示×

溫馨提示×

您好,登錄后才能下訂單哦!

密碼登錄×
登錄注冊×
其他方式登錄
點擊 登錄注冊 即表示同意《億速云用戶服務條款》

從String類中看C++當中的深拷貝與淺拷貝解

發布時間:2020-07-24 03:27:42 來源:網絡 閱讀:943 作者:暮回_zz 欄目:編程語言

    了解過C++語言的人,都應該知道,C++語言中的構造函數,析構函數,拷貝構造函數,賦值運算符重載函數,如果不定義,編譯器會自動生成的,當然,生成的只是一些最基本的,在達不到我們要求的條件下,就需要我們自己重新定義這些函數。

    我們現在說的講的是深拷貝與淺拷貝,當然討論這個問題的基礎,一般情況下是我們定義的變量是以指針形式出現的,原因就在于,不論賦值還是拷貝,我們要實現兩個指針指向的內容一致,那我得到新的指針和原指針是指向同一塊內存空間還是兩塊內存空間的相同內容。如果是指向同一塊空間,就存在了安全隱患,我們在自己管理空間時,就很有可能對一塊空間進行了多次的釋放,有些編譯器下會報錯,甚至直接奔潰,有些編譯器雖不會拋出異常,但也會對后續的程序造成未知的錯誤。

 

那么,現在就以String為例,看看如何解決這些問題。

 

//參數列表中,pstr為char* 類型,s為String類型

//實現方法1:

class String
{
 friend ostream& operator<<(ostream& _out, const String& s);
public:
 String(const char* pstr) :_str(new char[strlen(pstr)+1])
 {
  strcpy(_str,pstr);
  cout << "構造" << endl;//做標識
 }
 String(const String& s) :_str(new char[strlen(s._str) + 1])
 {
  strcpy(_str,s._str);
  cout << "拷貝構造"<<endl;//做標識
 }
 String& operator = (const String& s)
 {
  if (this == &s)//不給自己賦值,防止對一塊空間進行二次析構
  {
   char* tmp = (new char[strlen(s._str) + 1]);
   strcpy(tmp, s._str);
   delete[]_str;
   _str = tmp;
  }
  cout << "賦值重載" << endl;//做標識
  return *this;  //注意返回值
 }
 ~String()
 {
  if (this != NULL)
  {
   delete[]_str;
   _str = NULL;
  }
  cout << "析構" <<endl;//做標識
 }
private:
 char *_str;
};
//輸出運算符重載
ostream& operator<<(ostream& _out,const String& s)
{
 _out << s._str<< endl;
 return _out;
}

 

//*****************************************************************************************

 

//String類的實現2

class String
{
 friend ostream& operator<<(ostream& _out, const String& s);
public:
 String(const char* str) :_str(new char[strlen(str)+1])//同上
 {
  strcpy(_str,str);
 }
 //拷貝構造
 String(const String& s) : _str(NULL)
 {
  String tmp(s._str);
  std::swap(_str,tmp._str);
 }
 //賦值運算符重載
 //String&operator=(const String& s)
 //{
 // if (this != &s)
 // {
 //  char* tmp(s._str);//用s._str或者s實例化tmp都可以
 //  std::swap(_str,tmp);
 // }
 // return *this;
 //}
 
 //賦值運算符重載之開辟空間法
 String&operator=(const String& s)
 {
  if (this != &s)
  {
   char* tmp = new char[strlen(s._str) + 1];
   strcpy(tmp,s._str);
   delete[]_str;
   _str = tmp;
  }
  return *this;
 }
 //析構
 ~String()
 {
  if (NULL == _str)
  {
   delete[] _str;
   _str = NULL;
  }
 }
private:
 char* _str;
};
//輸出運算符重載
ostream& operator<<(ostream& _out,const String& s)
{
 _out << s._str<< endl;
 return _out;
}

 

// String類的實現3------>淺拷貝實現防止內存的多次釋放

class String
{
 friend ostream& operator<<(ostream& _out, const String& s);
public:
 String(const char* pdata)
  :_str(new char[strlen(pdata)+1])
  , _count(new int)
 {
  strcpy(_str,pdata);
  *_count = 1;
 }
 String(const String& s)
  :_str(s._str)
  , _count(s._count)
 {
  _count++;
 }
 
 String& operator=(const String& s)
 {
  if (this != &s)
  {
   if (--(*_count) == 0)
   {
    delete[]_str;
    delete _count;
   }
   _count = s._count;
   _str = s._str;
   _count++;
  }
  return* this;
 }
 ~String()
 {
  if (--(*_count) == 0)
  {
   delete[] _str;
   delete _count;
  }
 }
private:
 char* _str;
 int* _count;
};
//輸出運算符重載
ostream& operator<<(ostream& _out,const String& s)
{
 _out << s._str<< endl;
 return _out;
}

//*****************************************************************************************

友元函數受第一參數的限制,只能采用類外定義,引入友元

方法三,關于引入計數器,在面試過程中,這是最不推薦的方法,HR往往更傾向于讓你寫出深拷貝的方法。

 

深拷貝與淺拷貝是面試過程中經常出現的題目,弄清楚這類問題是非常必要的

 

 

 

 

向AI問一下細節

免責聲明:本站發布的內容(圖片、視頻和文字)以原創、轉載和分享為主,文章觀點不代表本網站立場,如果涉及侵權請聯系站長郵箱:is@yisu.com進行舉報,并提供相關證據,一經查實,將立刻刪除涉嫌侵權內容。

AI

灌云县| 翁源县| 怀远县| 科技| 武穴市| 三亚市| 漳平市| 会昌县| 武城县| 柘荣县| 灵台县| 合川市| 铁岭县| 台中县| 宜州市| 梨树县| 靖西县| 虹口区| 鹤庆县| 厦门市| 巴南区| 岐山县| 双鸭山市| 勐海县| 青冈县| 云安县| 尼木县| 阿拉善左旗| 霍林郭勒市| 盐源县| 崇州市| 新源县| 崇礼县| 开鲁县| 鄂托克前旗| 于都县| 象山县| 柳林县| 修文县| 开平市| 阜宁县|