1,本文講述數組操作符重載,上篇博文的字符串類 string 確實強大,但 string 類 對象還具備 C 方式字符串的靈活性嗎?還能直接訪問單個字符嗎?
1,C 方式字符串靈活性是指能夠通過數組訪問操作符方便的訪問字符串中的單個字符;
2,字符串類的兼容性:
1,string 類最大限度的考慮了 C 字符串的兼容性;
2,可以按照使用 C 字符串的方式使用 string 對象;
3,代碼示例:
1 string s = "a1b2c3d4e"; 2 int n = 0; 3 4 for(int i=0; i<s.length(); i++) 5 { 6 if( isdigit(s[i]) ) 7 { 8 n++; 9 } 10 }
3,用 C 方式使用 string 類編程實驗:
1,main.cpp 文件:
1 #include <iostream> 2 #include <string> 3 4 using namespace std; 5 6 int main() 7 { 8 string s = "a1b2c3d4e"; 9 int n = 0; 10 11 for(int i = 0; i<s.length(); i++) 12 { 13 if( isdigit(s[i]) ) 14 { 15 n++; 16 } 17 } 18 19 cout << n << endl; 20 21 return 0; 22 }
2,輸出結果:
4
3,在任意的 C++ 編譯器中都支持數組訪問的方式來使用字符串對象;
4,問題:
1,類的對象怎么支持數組的下標訪問?
1,C++ 編譯器並不支持將數組訪問操作符和任意的類對象一起使用;
5,重載數組訪問操作符:
1,數組訪問符是 C/C++ 中的內置操作符;
1,數組訪問操作符地位和 “+”、“-”、“*”、“/”、“==”、“=” 等內置操作符地位一致;
2,是操作符、地位同上,意味着可以重載;
2,數組訪問符的原生意義是數組訪問和指針運算;
1,a[n] <==> *(a + n) <==> *(n + a) <==> n[a];
1,指針和最終偏移地址相加,然后取元素;
2,加法交換律;
2,訪問數組中的元素深層次的意義就是指針運算,算偏移量;
6,指針與數組的復習實例分析:
1,main.cpp 文件:
1 #include <iostream> 2 #include <string> 3 4 using namespace std; 5 6 int main() 7 { 8 int a[5] = {0}; 9 10 for(int i=0; i<5; i++) 11 { 12 a[i] = i; 13 } 14 15 for(int i=0; i<5; i++) 16 { 17 cout << *(a + i) << endl; // ==> cout << a[i] << endl; 18 } 19 20 cout << endl; 21 22 for(int i=0; i<5; i++) 23 { 24 i[a] = i + 10; // ==> a[i] = i + 10; 25 } 26 27 for(int i=0; i<5; i++) 28 { 29 cout << *(i + a) << endl; // cout << a[i] << endl; 30 } 31 32 return 0; 33 }
2,輸出結果:
1 0 2 1 3 2 4 3 5 4 6 7 10 8 11 9 12 10 13 11 14
2,結論:
1,數組訪問操作符原生語義是訪問數組中的某個元素,深層次的意義是算地址的偏移量;
7,重載數組訪問操作符:
1,數組訪問操作符([]):
1,只能通過類的成員函數重載;
2,重載函數能且僅能使用一個參數;
1,參數可以是不同的類型;
3,可以定義不同參數的多個重載函數;
8,重載數組訪問操作符編程實驗:
1,main.cpp 文件:
1 #include <iostream> 2 #include <string> 3 4 using namespace std; 5 6 class Test 7 { 8 int a[5]; // 被模擬的數組; 9 public: 10 int& operator [] (int i) // 能且僅能重載一個參數;引用是為了可以當做左值,因為不引用則直接是函數調用的返回值,它是不能當做左值使用的; 11 { 12 return a[i]; // 這里返回的不是局部變量,所以可以返回引用,且引用能夠返回位置; 13 } 14 15 /* 通過字符串來訪問數組 */ 16 int& operator [] (const string& s) // 定義多個重載函數;引用是為了可以當做左值; 17 { 18 if( s == "1st" ) 19 { 20 return a[0]; 21 } 22 else if( s == "2nd" ) 23 { 24 return a[1]; 25 } 26 else if( s == "3rd" ) 27 { 28 return a[2]; 29 } 30 else if( s == "4th" ) 31 { 32 return a[3]; 33 } 34 else if( s == "5th" ) 35 { 36 return a[4]; 37 } 38 39 return a[0]; 40 } 41 42 int length() 43 { 44 return 5; 45 } 46 }; 47 48 int main() 49 { 50 Test t; 51 52 for(int i=0; i<t.length(); i++) 53 { 54 t[i] = i; 55 } 56 57 for(int i=0; i<t.length(); i++) 58 { 59 cout << t[i] << endl; 60 } 61 62 cout << t["5th"] << endl; // 通過字符串作為下標來訪問數組; 63 cout << t["4th"] << endl; 64 cout << t["3rd"] << endl; 65 cout << t["2nd"] << endl; 66 cout << t["1st"] << endl; 67 68 return 0; 69 }
2,結論:
1,在以后工作中要學習 C++ 后續語言如 C#、D 等語言時,會發現確實可 以將字符串作為下標來訪問一個數組,它就是應用了操作符重載來實現的;
9,數組類的完善編程實驗:
1,IntArray.h 文件:
1 #ifndef _INTARRAY_H_ 2 #define _INTARRAY_H_ 3 4 class IntArray 5 { 6 private: 7 int m_length; 8 int* m_pointer; 9 10 IntArray(int len); 11 IntArray(const IntArray& obj); 12 bool construct(); 13 public: 14 static IntArray* NewInstance(int length); 15 int length(); 16 bool get(int index, int& value); 17 bool set(int index ,int value); 18 int& operator [] (int index); // 數組訪問操作符重載; 19 IntArray& self(); // 返回自身,為了不使用指針; 20 ~IntArray(); 21 }; 22 23 #endif
2,IntArray.cpp 文件:
1 #include "IntArray.h" 2 3 IntArray::IntArray(int len) 4 { 5 m_length = len; 6 } 7 8 bool IntArray::construct() 9 { 10 bool ret = true; 11 12 m_pointer = new int[m_length]; 13 14 if( m_pointer ) 15 { 16 for(int i=0; i<m_length; i++) 17 { 18 m_pointer[i] = 0; 19 } 20 } 21 else 22 { 23 ret = false; 24 } 25 26 return ret; 27 } 28 29 IntArray* IntArray::NewInstance(int length) 30 { 31 IntArray* ret = new IntArray(length); 32 33 if( !(ret && ret->construct()) ) 34 { 35 delete ret; 36 ret = 0; 37 } 38 39 return ret; 40 } 41 42 int IntArray::length() 43 { 44 return m_length; 45 } 46 47 bool IntArray::get(int index, int& value) 48 { 49 bool ret = (0 <= index) && (index < length()); 50 51 if( ret ) 52 { 53 value = m_pointer[index]; 54 } 55 56 return ret; 57 } 58 59 bool IntArray::set(int index, int value) 60 { 61 bool ret = (0 <= index) && (index < length()); 62 63 if( ret ) 64 { 65 m_pointer[index] = value; 66 } 67 68 return ret; 69 } 70 71 int& IntArray::operator [] (int index) // 數組訪問操作符重載實現; 72 { 73 return m_pointer[index]; 74 } 75 76 IntArray& IntArray::self() // 返回數組指針的引用; 77 { 78 return *this; 79 } 80 81 IntArray::~IntArray() 82 { 83 delete[]m_pointer; 84 }
3,main.cpp 文件:
1 #include <iostream> 2 #include <string> 3 #include "IntArray.h" 4 5 using namespace std; 6 7 int main() 8 { 9 IntArray* a = IntArray::NewInstance(5); // 通過智能指針對象代替這里的指針; 10 11 if( a != NULL ) 12 { 13 IntArray& array = a->self();//堆空間創建的對象,沒有別名, 這里給它起一個別名; 14 15 cout << "array.length() = " << array.length() << endl; 16 17 array[0] = 1; 18 19 for(int i=0; i<array.length(); i++) 20 { 21 cout << array[i] << endl; 22 } 23 } 24 25 delete a; 26 27 return 0; 28 }
10,小結:
1,string 類最大程度的兼容了 C 字符串的用法;
2,數組訪問符的重載能夠使得對象模擬數組的行為;
3,只能通過類的成員函數重載數組訪問操作符;
4,重載函數能且僅能使用一個參數;