這里直接實現深拷貝的String類
#PRagma once#define _CRT_SECURE_NO_WARNINGS 1#include<iostream>using namespace std;//面試題1:賦值運算符函數//模擬實現Stringclass String{public: //構造函數 String(const char* _pStr = "") { if (_pStr == NULL) { pstr = new char[1]; *pstr = '/0'; } else { pstr = new char[strlen(_pStr) + 1]; strcpy(pstr, _pStr); } } //拷貝構造函數 //String(String s) 這種是錯誤的寫法,會導致無限遞歸調用 String(const String &s) { //如果不是自身拷貝 if (this != &s) { delete[] pstr; pstr = new char[strlen(s.pstr)]; strcpy(pstr, s.pstr); } } //注意點1:返回值為String的引用,保證了其可以連續賦值 //注意點2:穿入參數為s的引用,減少其調用拷貝構造函數而造成的開銷 //注意點3:記得用delete釋放申請的空間,防止出現內存泄漏 //注意點4:是否判斷傳入的參數和自身是否為同一個實例 //注意點5:中間采用了臨時變量tmp。如果不用tmp,先釋放了原來的空間;如果此時由于 // 內存不足而導致new不出來拋出異常時,pstr便成了一個空指針 //解決方法1:申請char*的臨時變量,釋放后賦值給pstr /*String& Operator=(const String&s) { if (&s != this) { char* tmp = new char[strlen(s.pstr)+1]; strcpy(tmp, s.pstr); delete[] pstr; pstr = tmp; } return *this; }*/ //解決方法2:構造出一個新的變量,將其和this進行交換 //調用了一次構造函數和一次析構函數 /*String& operator=(const String&s) { if (this != &s) { String tmp(s.pstr); std::swap(pstr, tmp.pstr); } return *this; }*/ //解決方法3:進行值傳入,直接交換 //調用了一次拷貝構造函數和一次析構函數 String& operator=(String s) { std::swap(pstr, s.pstr); } //注意點:釋放空指針不會導致出錯,但空間不允許釋放多次 ~String() { if (pstr != NULL) { delete[] pstr; pstr = NULL; } }protected: char* pstr;};注意點總結:
1、返回值為String的引用,保證了其可以連續賦值
2、穿入參數為s的引用,減少其調用拷貝構造函數而造成的開銷
3、記得用delete釋放申請的空間,防止出現內存泄漏
4、是否判斷傳入的參數和自身是否為同一個實例
5、中間采用了臨時變量tmp。如果不用tmp,先釋放了原來的空間;如果此時由于內存不足而導致new不出來拋出異常時,pstr便成了一個空指針
新聞熱點
疑難解答