我写了一个IntegerMatrix类来添加我自己的方法来处理矩阵。现在我写了这样一个函数:
IntegerMatrix** IntegerMatrix::multiplyMatrix(IntegerMatrix** table2)
(这是一个双指针,因为我拿着一大堆指向4x4 2D数组的指针。)所以我只能做到这一点:
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 :(得分:1)
我不明白你的问题,但这里是矩阵乘法规范如何工作的简短演示:
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 :(得分:1)
你可能会以Cargo-Cult programming的意义上传承一些文物。 : - /
例如:我猜你的multiplyMatrix原型上的双重间接(**
)就在那里,因为你在某处看到了多维数组的整数...像:
void printMatrix(int ** myMatrix, int rows, int columns);
双重间接只是一个指向指针的指针。这是实现passing low-level C-style 2D arrays as parameters的具体实施点的一种方式。但是,如果您正在使用恰好代表Matrix的抽象类,那么这不是您必须要解决的问题。因此,一旦您将矩阵大小和数据本身封装在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 reference移动构造,并且存在各种各样的棘手问题。
真的有很多细微差别。如果你正在做这个教育练习,我建议你慢慢来,并通过一个教程,引导你完成每一步,而不是直接跳到火上。如果您在矩阵中使用低级C数组和动态分配,请将它们更改为std::vector
std::vector
。
答案 2 :(得分:1)
对于一个IntegerMatrix
对象,您使用this->table[i][k]
来引用您保存矩阵数据的数组,而table2
对象引用和{{1} }指针,您正在使用result
和table2[k][j]
。
我认为你想要做的是:
result[i][j]