c++ assignment operator implementation in templated class
I'm building my own matrix class to solidify my c++ understanding. It's templated, so I can have an int matrix or a float, or boolean matrix. I wasn't goi开发者_开发知识库ng to implement a copy constructor or assignment operator or a destructor, because I'm not going to have any dynamic member elements but if I have:
Matrix<float,3,4> mat1;
Matrix<int,45,45> mat2;
mat1 = mat2;
it returns the following error:
/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>&)
which, if the two matrices are both float or both int, it's ok. Dimensions don't have to match. So the default assignment operator works great unless they are of different types. So I implement my own assignment operator:
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;
}
This works if they are different types, but same dimensions- but the values in the second are converted from the second type to the first. My question is, 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?
The problem you're having is that you have three types, but you only mention two. Fundamentally,
Matrix<float,3,4> mat1;
Matrix<int,45,45> mat2;
mat1 = mat2;
Can't work, because the result of the assignment should be Matrix<float, 45, 45>
, but mat1
is of type Matrix<float, 3, 4>
. This cannot possibly be changed.
Is there a reason the dimensions of the matrices must be part of the type? it seems like you really want to have this stuff change around dynamically. Just do:'
template <class T>
class Matrix
{
unsigned int rows;
unsigned int cols;
public:
Matrix(numrows, numcols): rows(numrows), cols(numcols) {}
};
etc... Then you can have the dimensions of the matrices change at runtime.
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?
You don't.
mat
does not point at a Matrix<float,3,4>
; it is a Matrix<float,3,4>
. It can't ever be anything else. There is no way to turn mat
into a Matrix<int,45,45>
.
If you want to be able to point to different objects, you need to use pointers (or references). In order to be able to have a pointer that can point to any specialization of Matrix
, you need to create a base class and derive Matrix
from that base class:
class MatrixBase { };
template <typename T, unsigned Rows, unsigned Columns>
class Matrix : public MatrixBase { };
You can then use a MatrixBase*
to point to an object of any Matrix
type and you can use a MatrixBase&
to refer to an object of any Matrix
type. You will need to put as much shared functionality as you can into the MatrixBase
class or make use of virtual functions.
精彩评论