C++筆記 第三十六課 經典問題解析三---狄泰學院
阿新 • • 發佈:2018-11-15
如果在閱讀過程中發現有錯誤,望評論指正,希望大家一起學習,一起進步。
學習C++編譯環境:Linux
第三十六課 經典問題解析三
1.關於賦值的疑問
什麼時候需要過載賦值操作符?編譯器是否提供預設的賦值操作?
編譯器為每個類預設過載了賦值操作符
預設的賦值操作符僅完成淺拷貝
當需要進行深拷貝時必須過載賦值操作符
賦值操作符與拷貝建構函式有相同的存在意義
36-1 預設賦值操作符過載
#include <iostream> #include <string> using namespace std; class Test { int* m_pointer; public: Test() { m_pointer = NULL; } Test(int i) { m_pointer = new int(i); } //自定義拷貝建構函式 Test(const Test& obj) { m_pointer = new int(*obj.m_pointer);/*從堆空間申請一片記憶體,這片記憶體代表int型別的值,取值引數物件point指標所指向的堆空間中的整型值,將整個整型值取出來,並且賦值到新申請的這片記憶體空間去,這樣完成拷貝建構函式的操作*/ } //賦值操作符過載函式原型,返回值型別一定是一個引用,為了連續賦值 //引數必須是const型別的引用型別 //賦值操作不是自賦值 //返回當前物件 Test& operator = (const Test& obj) { if( this != &obj ) { delete m_pointer; m_pointer = new int(*obj.m_pointer); } return *this;//返回當前物件 } void print() { cout << "m_pointer = " << hex << m_pointer << endl; } ~Test() { delete m_pointer; } }; int main() { Test t1 = 1; Test t2; t2 = t1; t1.print(); t2.print(); return 0; }
問題分析
一般性原則
過載複製操作符,必然需要實現深拷貝!!!
IntArray 陣列類的優化
2.不積跬步無以至千里
編譯器預設提供的函式
class Test //類 { public: Test(); //無參建構函式---與類同名的成員函式 Test(const Test&); //拷貝建構函式 Test& operator = (const Test&); //賦值操作符過載函式 ~Test(); //預設解構函式 }
面試題目:如果只是定義了一個類,那裡面是不是空的呢?
雖然什麼都沒有不是,因為編譯器會為空的類放一些東西,就是四個函式實現。
3.關於string的疑問
下面的程式碼輸出什麼?為什麼?
36-2 字串問題1
//產生野指標 #include <iostream> #include <string> using namespace std; int main() { string s = "12345"; const char* p = s.c_str(); cout << p << endl; s.append("abced"); //出現錯誤的原因: p成為了野指標 cout << p << endl; return 0; } 執行結果 12345 12345abced
問題分析
string物件內部維護了一個指向資料的char*指標,這個指標可能在程式執行的過程中發生改變。
下面的程式輸出什麼?為什麼?
36-3 字串問題2
正確的程式碼:
#include <iostream>
#include <string>
using namespace std;
int main()
{
const char* p = "12345";
string s = "";
s.reserve(10);
for(int i=0; i<5; i++)
{
s[i] = p[i];
}
if( !s.empty() )
{
cout << s << endl;
}
for(int i=0; i<5; i++)
{
cout << s[i] << endl;
}
return 0;
}
執行結果
1
2
3
4
5
錯誤的程式碼:
#include <iostream>
#include <string>
using namespace std;
int main()
{
const char* p = "12345";
string s = "";
s.reserve(10);
//下面for迴圈執行結束後m_length=0沒有改變,所以之後輸出為空
for(int i=0; i<5; i++)
{
s[i] = p[i];
}
cout << s << endl;
return 0;
}
執行結果為空
問題分析
小結
在需要進行深拷貝的時候必須過載賦值操作符
賦值操作符和拷貝建構函式有同等重要的意義
string類通過一個數據空間儲存字元資料
string類通過一個成員變數儲存當前字串的長度
C++開發時儘量避開C語言中慣用的程式設計思想