07. november 2006 - 14:56Der er
9 kommentarer og 1 løsning
2D Array med proxy klasse
Hejsa
Har en 2D Table class, som umiddelbart virker fint nok. Dog er jeg ikke helt tilfreds med den måde jeg tildeler Table en ny værdi.
minTable(1,1) = 23; Ønsker at det skal foregå på følgende måde. minTable[1][1] = 23; Og har fundet frem til at det skulle være muligt, hvis man benytter sig af en proxy klasse.
Har fundet følgende eksempel. template<class T> class Array2D { public: class Array1D { public: T& operator[](int index); const T& operator[](int index)const; ... }; Array1D operator[](int index); const Array1D operator[](int index)const; ... };
Så skulle det være muligt. Håber nogen kan hjælpe mig med at få det overført til min egen kode, da jeg ikke lige umiddelbart kan få det til at virke selv.
//Table.h #ifndef TABLE_H #define TABLE_H
template <typename T> class Table { public: Table(); Table(int m, int n); Table(int m, int n, const T& value); Table(const Table<T>& rhs); ~Table();
Table<T>& operator=(const Table& rhs); T& operator()(int i , int j);
int numRows()const; int numCols()const;
void resize(int m, int n); void resize(int m, int n, const T& value); private: void destroy(); private: int mNumRows; int mNumCols; T** mDataMatrix; };
//Reallocate the table based on rhs info. resize(rhs.mNumRows, rhs.mNumCols);
//Copy the entries over element-by-element. for(int i = 0; i < mNumRows; ++i) for(int j = 0; j < mNumCols; ++j) mDataMatrix[i][j] = rhs.mDataMatrix[i][j];
//return a reference to *this so we can do chain //assignments: x = y = z = w = ... return *this; }
template <typename T> T& Table<T>::operator ()(int i, int j) { return mDataMatrix[i][j]; //return the ijth table entry. }
template <typename T> int Table<T>::numRows() const { return mNumRows; }
template <typename T> int Table<T>::numCols() const { return mNumCols; }
template <typename T> void Table<T>::resize(int m, int n) { //Call resize and use default constructor T() as 'value' resize(m, n, T()); }
template <typename T> void Table<T>::resize(int m, int n, const T &value) { //Destroy destroy();
// Save dimensions. mNumRows = m; mNumCols = n;
//Allocate a row (array) of pointers. mDataMatrix = new T*[mNumRows];
//Now loop through each pointer in this row array. for(int i = 0; i < mNumRows; ++i) { //And allocate a column (array) to build the table. mDataMatrix[i] = new T[mNumCols];
//now loop through each element in this row[i] //and copy 'value' into it. for(int j = 0; j < mNumCols; ++j) mDataMatrix[i][j] = value; } }
template <typename T> void Table<T>::destroy() { //Does the matrix exists? if(mDataMatrix) { for(int i = 0; i < mNumRows; ++i) { //does the ith row exist? if(mDataMatrix[i]) { //Yes, delete it. delete[]mDataMatrix[i]; mDataMatrix[i] = 0; } } //Delete the row array. delete[] mDataMatrix; mDataMatrix = 0; } mNumRows = 0; mNumCols = 0; }
#endif //TABLE_H
//Main.cpp #include "Table.h" #include <iostream> using namespace std;
Sejt, så virker det jo som det skal :-) Selvom jeg ikke helt forstår hvorfor.
Og sjovt nok har jeg ingen problemer med at compile når jeg bruger Table<T>::Table<T> tilgengæld har jeg endnu ikke fundet udaf hvordan jeg kan opdele min kode i en header fil og en cpp fil, når jeg benytter mig af templates.
Bruger Visual Studio 2005 hvis det er til nogen hjælp. (Tager gerne imod anbefalinger af andre programmer, da jeg ikke er imponeret over dens code completion, virker kun halvdelen af tiden)
lars314 hvis du også vil have lidt point for dit link, så smid lige et svar.
int numRows()const { return mNumRows; } int numCols()const { return mNumCols; }
void resize(int m, int n, const T& value = 0) { int i, j; for(i = 0; i < mNumRows; i++) delete [] DataMatrix[i]; delete [] DataMatrix; DataMatrix = new T * [m]; for(i = 0; i < m; i++) { DataMatrix[i] = new T[n]; for(j = 0; j < m; j++) DataMatrix[i][j] = value; } } int mNumRows; int mNumCols; T** DataMatrix; };
Grunden til at det virker er at når compileren ser den første [] checker den klassen for at se om den har en 'operator [](int)' funktion, og når den ikke kan finde den prøver den at finde en anden måde at kompilere det på. Det er her den nye 'operator T**()' kommer ind i billedet, for nu kan kompileren automatiske konvertere din klasse til typen T** og så bruge [][] til at indeksere deri. Når kompileren er færdig, står der faktisk 'minTable.mDataMatrix[i][j]' hvilket nok er så hurtigt som det kan gøres :)
Jeg brugte gcc til at kompilere med, så det er nok den der har fået det galt i halsen.
Hvis din code completion ikke virker, kan det være fordi der er fejl i koden og parseren ikke kan forstå hvad der står. Det sker også tit for mig med msvc, men ligeså snart det er rettet virker det igen.
Må hellere til at få lukket spørgsmålet, men i skal ihvertfald have tak. Bertelbrander hvis du også vil have lidt point for dit eksempel, kan du så ikke lige smide et svar inden alt for længe.
Tilladte BB-code-tags: [b]fed[/b] [i]kursiv[/i] [u]understreget[/u] Web- og emailadresser omdannes automatisk til links. Der sættes "nofollow" på alle links.