2010-12-09 13 views
1

Ich baue meine eigene Matrix-Klasse, um meine C++ Verständnis zu festigen. Es ist templated, also kann ich eine int-Matrix oder einen Float oder eine boolesche Matrix haben. Ich wollte keine Kopie Konstruktor oder Zuweisungsoperator oder einen destructor implementieren, weil ich keine dynamischen Bauteilelemente haben gehen, aber wenn ich:C++ Zuweisung Operatorimplementierung in Vorlagenklasse

Matrix<float,3,4> mat1; 
Matrix<int,45,45> mat2; 
mat1 = mat2; 

es gibt die folgende Fehlermeldung:

/Users/Jake/Dropbox/C++/test.cpp: In function ‘bool test1()’: 
/Users/Jake/Dropbox/C++/test.cpp:23: error: no match for ‘operator=’ in ‘m2 = m1’ 
/Users/Jake/Dropbox/C++/Matrix.h:22: note: candidates are: Matrix<float, 3u, 4u>& Matrix<float, 3u, 4u>::operator=(const Matrix<float, 3u, 4u>&) 

was, wenn die beiden Matrizen float oder beide int sind, ist es in Ordnung. Dimensionen müssen nicht übereinstimmen. Daher funktioniert der Standardzuweisungsoperator sehr gut, es sei denn, sie haben unterschiedliche Typen. So implementieren ich meinen eigenen Zuweisungsoperator:

template <class T, unsigned int rows, unsigned int cols> 
template <class T2, unsigned int rows2, unsigned int cols2> 
Matrix<T, rows2, cols2> & Matrix<T,rows,cols>::operator= (const Matrix<T2, rows2, cols2> & second_matrix){ 
     unsigned int i,j; 
for (i=0; i < rows2; i++){ 
    for (j=0; j < cols2; j++){ 
     data[i][j] = second_matrix(i,j);  
    } 
} 
this->_rows = rows2; 
this->_cols = cols2; 
return *this; 
} 

Dies funktioniert, wenn sie unterschiedliche Typen sind, aber gleiche ABMESSUNGEN aber die Werte in den zweiten von dem zweiten Typ zum ersten umgewandelt. Meine Frage ist, wie kann ich es einrichten, so dass sie verschiedene Arten und unterschiedliche Dimensionen sein können, und nur dieses auf den zweiten oder eine Kopie des zweiten Punktes setzen?

+0

Wie kann ich es einrichten, so dass sie verschiedene Typen und verschiedene Dimensionen haben können, und nur diese auf den zweiten oder eine Kopie der Sekunde zeigen? es wurde bereits erklärt, dass Sie nicht, C++ verhindert Ihnen die Durchführung von Operationen auf Matrizen, die nicht in der Matrix-Theorie existiert - Sie können keine Matrizen zuweisen, die Dimensionen sind nicht identisch. –

Antwort

1

Das Problem, das Sie haben, ist, dass Sie drei Arten haben, aber Sie erwähnen nur zwei. Grundsätzlich

Matrix<float,3,4> mat1; 
Matrix<int,45,45> mat2; 
mat1 = mat2; 

kann nicht funktionieren, da das Ergebnis der Zuordnung sollte Matrix<float, 45, 45> sein, aber mat1 ist vom Typ Matrix<float, 3, 4>. Dies kann nicht geändert werden.

Gibt es einen Grund, warum die Abmessungen der Matrizen Teil des Typs sein müssen? es scheint, als ob du wirklich willst, dass sich dieses Zeug dynamisch verändert. Just do: '

template <class T> 
class Matrix 
{ 
    unsigned int rows; 
    unsigned int cols; 
    public: 
    Matrix(numrows, numcols): rows(numrows), cols(numcols) {} 
}; 

etc ... Dann können Sie die Abmessungen der Matrizen zur Laufzeit ändern.

+0

Genau was ich dachte? Warum sind die Dimensionen der Matrix Teil des Typs und nicht Variablen in ihm? – Zepee

+0

Aber das ist eine komplett andere Matrix-Klasse, sie ist nicht mehr auf Stack, sie muss ihre Elemente dynamisch zuweisen. Da Operationen auf dichten Matrizen sehr langsam sind, sind die Größen typischerweise nicht so groß, so dass es vorteilhaft ist, stapelzugewiesene Matrizen zu verwenden. –

+0

Wenn Sie mich fragen, ziehe ich es vor, die Dimensionen in den Typ zu schreiben, weil ich es nicht für sinnvoll halte, die Dimensionen einer Matrix zu ändern. Das Plakat möchte diesen Auftrag jedoch ausführen, und dies wäre die Folge. – SingleNegationElimination

1

how can I set it up so that they can be different types and different dimensions, and just set this to point at the second, or a copy of the second?

Sie nicht.

mat zeigt nicht auf eine Matrix<float,3,4>; es ist ein Matrix<float,3,4>. Es kann niemals etwas anderes sein. Es gibt keine Möglichkeit, mat in eine Matrix<int,45,45> zu verwandeln.

Wenn Sie auf verschiedene Objekte zeigen möchten, müssen Sie Zeiger (oder Referenzen) verwenden. Um einen Zeiger zu haben, in der Lage sein, die auf jede Spezialisierung von Matrix zeigen können, müssen Sie eine Basisklasse erstellen und leiten Matrix von dieser Basisklasse:

class MatrixBase { }; 

template <typename T, unsigned Rows, unsigned Columns> 
class Matrix : public MatrixBase { }; 

Sie können dann ein MatrixBase* verwenden, um ein Punkt Objekt von einem Matrix Typ und Sie können ein MatrixBase& verwenden, um auf ein Objekt eines beliebigen Matrix Typs zu verweisen. Sie müssen so viele freigegebene Funktionen wie möglich in die Klasse MatrixBase einfügen oder virtuelle Funktionen verwenden.

+0

Sind Sie sicher, dass Sie wollen, dass 'Rows' und' Cols' 'typename's sind und nicht' unsigned int''s? – SingleNegationElimination

+0

@TokenMacGuy: Was meinst du? Sie sind "unsigniert"! : -O (Danke, ha ha) –

Verwandte Themen