Реализация оператора присваивания c ++ в шаблонном классе - PullRequest
1 голос
/ 10 декабря 2010

Я строю свой собственный матричный класс, чтобы укрепить мое понимание c ++.Это шаблонно, так что я могу иметь матрицу типа int или число с плавающей точкой или логическую матрицу.Я не собирался реализовывать конструктор копирования или оператор присваивания или деструктор, потому что у меня не будет никаких динамических элементов-членов, но если у меня есть:

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

, он возвращает следующую ошибку:

/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>&)

, что, если две матрицы являются как float, так и int, то все в порядке.Размеры не должны совпадать.Таким образом, оператор присваивания по умолчанию отлично работает, если только они не относятся к разным типам.Поэтому я реализую свой собственный оператор присваивания:

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;
}

Это работает, если они разных типов, но одинаковых размеров, но значения во втором преобразуются из второго типа в первый.У меня вопрос, как я могу настроить его так, чтобы они могли быть разных типов и разных размеров, и просто установить его так, чтобы он указывал на второй или копию второго?

Ответы [ 2 ]

1 голос
/ 10 декабря 2010

Проблема в том, что у вас есть три типа, но вы упоминаете только два. Принципиально,

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

Не может работать, потому что результат присваивания должен быть Matrix<float, 45, 45>, но mat1 имеет тип Matrix<float, 3, 4>. Это не может быть возможно изменить.

Есть ли причина, по которой размеры матриц должны быть частью типа? кажется, что вы действительно хотите, чтобы этот материал изменялся динамически. Просто сделай: '

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

и т. Д. ... Тогда вы можете изменить размеры матриц во время выполнения.

1 голос
/ 10 декабря 2010

как я могу настроить его так, чтобы они могли быть разных типов и разных размеров, и просто установить его так, чтобы он указывал на секунду или на копию второго?

Вы не.

mat не указывает на Matrix<float,3,4>; это Matrix<float,3,4>. Этого больше не может быть. Нет способа превратить mat в Matrix<int,45,45>.

Если вы хотите иметь возможность указывать на разные объекты, вам нужно использовать указатели (или ссылки). Чтобы иметь указатель, который может указывать на любую специализацию Matrix, вам нужно создать базовый класс и извлечь Matrix из этого базового класса:

class MatrixBase { };

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

Затем вы можете использовать MatrixBase* для указания на объект любого типа Matrix, а вы можете использовать MatrixBase& для ссылки на объект любого типа Matrix. Вам нужно будет добавить как можно больше общих функций в класс MatrixBase или использовать виртуальные функции.

...