2016-05-31 67 views
0

我想爲通用二維數組創建我自己的類。這是我到目前爲止有:用[] []運算符更改通用二維數組類的值

#pragma once 
#include <vector> 

using namespace std; 

template<class T> 
class My2DArray { 
private: 
    vector<vector<T>> array; 
    int width, height; 

public: 
    My2DArray() {} 
    My2DArray(int w, int h) : width(w), height(h) { 
     array.resize(w); 
     for (int i = 0; i < w; i++) { 
      array[i].resize(h); 
     } 
    } 

    ~My2DArray() {} 

    vector<T> operator[](int index) { 
     return array[index]; 
    } 

    T* at(int x, int y) { 
     return &array[x][y]; 
    } 

    int getWidth() { return width; } 
    int getHeight() { return height; } 
}; 

,因爲我有我自己的[]運營商對我的類,它返回一個vector<T>,而這又可以通過矢量類的默認[]運營商進行訪問,我希望我的類將像法線向量一樣工作,但似乎並不如此。下面顯示了我怎麼能或不能改變一個二維數組的元素有三種方式:

My2DArray<int> intArray1(5, 5); 
intArray1[0][0] = 2;    //does not work 
cout << intArray1[0][0] << "\n"; //prints 0 
/*-------------------------------------------*/ 
My2DArray<int> intArray2(5, 5); 
*intArray2.at(0,0) = 2;   //works 
cout << intArray2[0][0] << "\n"; //prints 2 
/*-------------------------------------------*/ 
vector<vector<int>> intArray3; 
intArray3.resize(5); 
for (int i = 0; i < 5; i++) { 
    intArray3[i].resize(5); 
} 
intArray3[0][0] = 2;    //works 
cout << intArray3[0][0] << "\n"; //prints 2 

有沒有辦法讓[][]運營工作,爲我自己的類或者我需要用我的.at(x,y)功能給我一個指針並使用它來修改一個值?

+2

您錯過了'operator []'的第二個重載,它允許'const My2DArray'能夠使用'[]'。另外,在這種情況下,你不應該使用'width'和'height'等外部變量。你正在使用'vector',而'vector'通過調用'size()'方法來知道它的維數。通過使用這些無關變量,您將增加發生錯誤的機會(由於未更新寬度和高度變量)。因此,您的構造函數可以簡單地爲:'My2DArray(int w,int h):array(w,std :: vector (h)){}'沒有任何循環。 – PaulMcKenzie

回答

3

您的operator[]返回矩陣列的新副本,效率非常低,不允許修改矩陣。如果您要訪問真正的矩陣元素,改變方法的返回類型引用:

vector<T> &operator[](size_t index) { 
    return array[index]; 
} 

size_t更爲合理,因爲你可能不希望負指數指數型)。

順便說一句,數組本身將更好地被初始化爲合適的尺寸:

My2DArray(size_t w, size_t h) : width(w), height(h), array(w, vector<T>(h)) {} 

而不是第一默認構造的,然後在構造函數體另外改變。