C++操作符重载之下标操作符 ([], [][])

自定义类型MyClass中如果含有STL顺序容器成员sequential_container<type>,可能希望定义MyClass::operator[]操作符;如果STL顺序容器是多维的sequential_constainer<sequential_constainer<...<type>...>,可能希望定义MyClass[][]...操作符。

[]


 

重载[]操作符:

1. 双目操作符,第一操作数是重载此操作符的对象,第二操作数是无符号下标。

2. C++不允许把下标操作符函数作为外部函数来定义,它只能是非静态的成员函数。

3. 为了能对数组赋值,一般将返回值声明为引用类型。

 

ReTurnType& MyClass::operator[](unsigned int idx);

 

例一:

 1 #include <iostream>
 2 #include <iomanip>
 3 #include <fstream>
 4 #include <string>
 5 #include <vector>
 6 
 7 using namespace std;
 8 
 9 class Data1d{
10 
11     vector<double> data1d;
12     int length1d;
13 
14     public:
15     Data1d(int lg=0, double elem=0):length1d(lg){
16         for (int i=0; i<lg; i++)
17           data1d.push_back(elem);
18         //length1d=data1d.size();
19     }
20 
21     void pushback(double elem){data1d.push_back(elem); ++length1d;}
22     void popback(){data1d.pop_back(); --length1d;}
23     int length(){return length1d;}
24 
25     double& operator[](const int idx){
26         if (idx < 0 || idx >= length1d){
27             cerr << "ERROR: Index Out of Range, Last Element Returned!" << endl;
28             return data1d[length1d - 1];
29         }
30         return data1d[idx];
31     }
32     friend ostream& operator<<(ostream&, Data1d&);
33 };
34 
35 ostream& operator<<(ostream& o, Data1d& mydata1d){
36     cout << "Data(" << mydata1d.length1d << "):\t";
37     for (int i=0; i<mydata1d.length1d; i++)
38       o << mydata1d[i] << ' ';
39     return o;
40 }
41 
42 int main(){
43     Data1d mydata1d(5,0);
44     cout << mydata1d << endl;
45 
46     for (int i=1; i<=5; i++)
47       mydata1d.pushback(i);
48     cout << mydata1d << endl;
49 
50     for (int i=0; i<=mydata1d.length(); i++)
51       mydata1d[i]=i;
52     cout << mydata1d << endl;
53 
54     mydata1d.popback();
55     cout << mydata1d << endl;
56 }

输出:

Data(5):        0 0 0 0 0
Data(10):       0 0 0 0 0 1 2 3 4 5
ERROR: Index Out of Range, Last Element Returned!
Data(10):       0 1 2 3 4 5 6 7 8 10
Data(9):        0 1 2 3 4 5 6 7 8

 [][]


 

[][]操作符。[][]无法作为一个操作符整体来定义或重载,因为C++不允许定义新的操作符。[][]的实现实际上是后面一个[]作用于前面一个[]的返回值上,以下例子中[][]是这样实现的:MyClass重载operator[],其返回类型为&vector<type>, 继续使用非重载的vector<type>::operator[], 得到type&.

例二:

 1 #include <iostream>
 2 #include <iomanip>
 3 #include <fstream>
 4 #include <string>
 5 #include <vector>
 6 
 7 using namespace std;
 8 
 9 class Data2d{
10 
11     vector<vector<double>> data2d;
12     int lengthx, lengthy;
13 
14 public:
15     Data2d(int lgx = 0, int lgy=0, double elem = 0):lengthx(lgx), lengthy(lgy){
16         vector<double> data1d;
17         for (int i = 0; i < lgx; i++){
18             data1d.clear();
19             for (int j = 0; j < lgy; j++)
20                 data1d.push_back(elem);
21             data2d.push_back(data1d);
22         }
23     }
24 
25     vector<int> size(){ return vector<int>{lengthx, lengthy}; }
26 
27     //reload operator[] and we can use "operator"[][]
28     vector<double>& operator[](const int idx){ return data2d[idx]; }
29 
30     friend ostream& operator<<(ostream&, Data2d&);
31 };
32 
33 ostream& operator<<(ostream& o, Data2d& mydata2d){
34     cout << "Data(" << mydata2d.lengthx << ", " << mydata2d.lengthy << ")" << endl;
35 
36     for (int i = 0; i < mydata2d.lengthx; i++){
37         for (int j = 0; j < mydata2d.lengthy; j++)
38             o << mydata2d.data2d[i][j] << '\t';
39         o << endl;
40     }
41     return o;
42 }
43 
44 int main(){
45     Data2d mydata2d(3, 5, 0);
46     cout << mydata2d << endl;
47 
48     vector<int> sz = mydata2d.size();
49     for (int i = 0; i < sz[0]; i++)
50         for (int j = 0; j < sz[1]; j++)
51             mydata2d[i][j] = i+j;
52     cout << mydata2d << endl;
53 }

输出:

Data(3, 5)
0       0       0       0       0
0       0       0       0       0
0       0       0       0       0

Data(3, 5)
0       1       2       3       4
1       2       3       4       5
2       3       4       5       6

 

 

 

 

posted on 2016-11-18 12:34  zhangyz017  阅读(2194)  评论(0编辑  收藏  举报

导航