N
Hallo,
Folgend eine schönere Implementierung. Der Ansatz greift auf die Container der STL zurück, um das Rad nicht neu zu erfinden. Somit ist die Matrix nichts anderes als ein Vektor von einem Vektor. Die Hilfsklasse MatrixVector wurde erstellt, damit der Benutzer der Klasse nicht den internen Zustand verändern kann, aber trotzdem die Index-Schreibweise verwenden kann.
class Matrix;
template<typename T>
class MatrixVector : private std::vector<T>
{
friend class Matrix;
public:
explicit MatrixVector()
: std::vector<T>()
{ }
MatrixVector(unsigned int size, const T& rhs)
: std::vector<T>(size, rhs)
{ }
std::vector<T>::reference operator[](unsigned int rhs)
{
return std::vector<T>::operator[](rhs);
}
std::vector<T>::const_reference operator[](unsigned int rhs)
{
return std::vector<T>::operator[](rhs);
}
};
template<typename T>
class Matrix
{
public:
/*
* Die Konstruktoren.
*/
Matrix()
: pRows(0), pColumns(0)
{ }
Matrix(const Matrix& other)
: pElements(other.pElements), pRows(other.pRows), pColumns(other.pColumns)
{ }
Matrix(unsigned int rows, unsigned int columns, const T& rhs=T())
{
resize(rows, columns, rhs);
}
// Ein Konstruktor, der die Matrix aus einem Teil einer anderen Matrix erzeugt.
Matrix(const Matrix& other, unsigned int rowBegin, unsigned int columnEnd, unsigned int rows, unsigned int columns)
{
resize(rows, columns);
for(int r=0; r<rows; ++r)
for(int c=0; c<columns; ++c)
pElements[r][c] = other.pElements[r+rowBegin][c+columnBegin]
}
/*
* Zuweisungsoperator.
*/
Matrix& operator=(const Matrix& other)
{
if(this != &other)
{
pElements = other.pElements;
pRows = other.rows;
pColumns = other.columns;
}
return *this;
}
/*
* Indexoperatoren.
*/
MatrixVector<T>& operator[](unsigned int rhs)
{
return pElements[rhs];
}
const MatrixVector<T>& operator[](unsigned int rhs) const
{
return pElements[rhs];
}
/*
* Die resize()-Methode: Anpassung der Größe der Matrix.
*/
void resize(unsigned int rows, unsigned int columns, const T& rhs=T())
{
// Anpassung des Zeilenvektors.
pElements.resize(rows, MatrixVector<T>(columns, rhs));
// Anpassung des Spaltenvektors.
for(int i=0; i<rows; ++i)
pElements[i].resize(columns, rhs);
pColumns = columns;
pRows = rows;
}
unsigned int rows() const
{
return pRows;
}
unsigned int columns() const
{
return pColumns;
}
unsigned int size() const
{
return pSize;
}
};
Wenn man das jetzt richtig fein machen wollte, könnte man natürlich auch noch Iteratoren (row_iterator, column_iterator und die entsprechende Gegenstücke mit dem const_ davor).
Niels