Собственный матричный оператор умножения

Я написал класс IntegerMatrix, чтобы добавить свои собственные методы для работы с матрицами. Теперь я написал такую ​​функцию:

IntegerMatrix** IntegerMatrix::multiplyMatrix(IntegerMatrix** table2)

(Это двойной указатель, потому что я держу огромный массив указателей на 2D-массивы 4×4.) Так что я просто мог сделать это:

matrix1.multplyMatrix(matrix2)

Одна маленькая проблема заключается в * не определено для моего собственного класса. Поэтому я решил перегрузить этот оператор, чтобы я мог сделать что-то вроде этого:

sum += this->table[i][k] * table2[k][j];

Но как я могу получить право i а также k в перегруженном операторе, который определяется так:

IntegerMatrix IntegerMatrix::operator*(const IntegerMatrix & k);

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

РЕДАКТИРОВАТЬ:

Я переписал это, и теперь у меня есть:

IntegerMatrix IntegerMatrix::operator*(const IntegerMatrix & table2)
{
int i, j, k;
int sum;
IntegerMatrix * result = new IntegerMatrix(SIZE);

for (i = 0; i < SIZE; i++) {
for (j = 0; j < SIZE; j++) {
sum = 0;
for (k = 0; k < SIZE; k++) {
sum += this->table[i][k] * table2[k][j];
}
result[i][j] = sum;
}
}
return *result;

}

Это дает мне только ошибку на []:

Binary '[' : 'IntegerMatrix' does not define this operator or a conversiont o a type acceptable to the predefined operator.

0

Решение

Я не понимаю ваш вопрос, но вот краткая демонстрация того, как работает умножение матриц normall:

class IntegerMatrix {
int table[3][3];

public:
IntegerMatrix& operator*=(const IntegerMatrix& rhs) {
//multiply table by rhs.table, store in data.
return *this;
}
};
IntegerMatrix operator*(IntegerMatrix lhs, const IntegerMatrix& rhs)
{return lhs*=rhs;} //lhs is a copy, so we can alter and return it

У вас есть код

IntegerMatrix * result = new IntegerMatrix(SIZE); //pointer to an IntegerMatrix
...
result[i][j] = sum; //assign sum to the jth index of matrix # i

когда на самом деле, я полагаю, вы хотели

result->table[i][j] = sum; //sum to the ixj index of the result matrix.

Кроме того, ваша функция протекает, потому что у вас есть new, но нет delete, Это легко исправить в вашем случае, так как вам не нужно новое. (Вы из Java или C # фона?)

IntegerMatrix result(SIZE);
...
result[i][j] = sum;
...
return result;

Независимо от всего вышесказанного, вы можете [] оператор для вашей целочисленной матрицы.

class row {
int* data;
int size;
public:
row(int* d, int s) :data(d), size(s) {}
int& operator[](int offset) {
assert(offset<size);
return data[offset];
}
};

row operator[](int column) {
assert(column<SIZE);
return row(table[column], SIZE);
}

И это позволит вам написать:

IntegerMatrix result;
result[i][j] = sum;
1

Другие решения

Вы можете носить некоторые артефакты, в некотором роде Cargo-Cult программирование смысл. : — /

Например: я предполагаю, что двойные косвенные**) на вашем прототипе для multiplyMatrix, потому что вы видели где-то многомерные массивы целых чисел … такие вещи, как:

void printMatrix(int ** myMatrix, int rows, int columns);

Двойная косвенность — это просто указатель на указатель. Это способ достижения конкретной точки реализации передача низкоуровневых 2D-массивов в стиле C в качестве параметров. Но это не то, что вам нужно решать, когда вы работаете с абстрактным классом, представляющим матрицу. Поэтому, как только вы инкапсулировали размер матрицы и сами данные в классе IntegerMatrix, вы не захотите что-то вроде этого:

void printMatrix(IntegerMatrix ** myMatrix);

Скорее всего, вы захотите передать простую ссылку на класс, который инкапсулирует данные, например:

void printMatrix(IntegerMatrix const & myMatrix);

Вы должны фактически вернуть новую матрицу из вашей функции умножения, по крайней мере, если вы используете ее для реализации перегрузки оператора … потому что семантически не имеет смысла для людей писать такие вещи, как a * b; и это изменить. (Может, но не следует.) Таким образом, у вас есть выбор: вернуть экземпляр значения матрицы:

IntegerMatrix IntegerMatrix::multiplyMatrix(IntegerMatrix const & rhs);

…или возвращая указатель на новый объект:

IntegerMatrix * IntegerMatrix::multiplyMatrix(IntegerMatrix const & rhs);

Возвращение по указателю исторически выбиралось многими библиотеками, потому что возвращение по значению из локальной переменной в функции потребовало бы создания копии во время возврата. Возвращение указателя происходит быстро (он «копирует» только одно 32-разрядное / 64-разрядное число), а копирование экземпляра объекта и больших блоков данных внутри него происходит медленно. Так что многие библиотеки будут просто использовать указатели Matrix везде … с проблемой, что становится трудно понять, чья ответственность в конечном итоге delete предмет. Умные указатели являются одним из способов обеспечения этого:

unique_ptr<IntegerMatrix> IntegerMatrix::multiplyMatrix(IntegerMatrix const & rhs);

Но C ++ 11 обладает некоторой хитрой способностью быть таким же быстрым без беспорядка. Если вы возвращаете что-то по значению из функции, и компилятор уверен, что значение больше не будет использоваться (так как оно выходит из области видимости), то его можно «перемещать» так же быстро, как указатель. Это требует от вас поддержки RValue ссылка, и в этом есть все виды хитрости.

Там действительно много нюансов. Если вы делаете это как учебное упражнение, я бы посоветовал взять его медленно и пройти учебник, который проведет вас через каждый шаг, а не прыгать прямо в огонь. И если вы используете низкоуровневые массивы C и динамические выделения внутри вашей матрицы, измените их на std::vector из std::vector,

1

Для одного IntegerMatrix объект, который вы используете this->table[i][k] ссылаться на массив, где вы держите матричные данные, а для table2 ссылка на объект и result указатель, вы используете table2[k][j] а также result[i][j],

Я думаю, что вы хотите сделать что-то вроде:

IntegerMatrix IntegerMatrix::operator*(const IntegerMatrix & table2)
{
int i, j, k;
int sum;
IntegerMatrix * result = new IntegerMatrix(SIZE);

for (i = 0; i < SIZE; i++) {
for (j = 0; j < SIZE; j++) {
sum = 0;
for (k = 0; k < SIZE; k++) {
sum += this->table[i][k] * table2.table[k][j];
}
result->table[i][j] = sum;
}
}
return *result;
}
1
По вопросам рекламы [email protected]