0

我编写了一个 IntegerMatrix 类来添加我自己的方法来处理矩阵。现在我写了一个这样的函数:

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

(这是一个双指针,因为我持有大量指向 4x4 2D 数组的指针。)所以我可以这样做:

matrix1.multplyMatrix(matrix2)

一个小问题是*没有为我自己的班级定义。所以我想重载这个运算符,我可以做这样的事情:

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

但是我怎样才能得到正确的ik在重载的运算符中,它的定义是这样的:

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.
4

3 回答 3

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;
于 2012-10-08T19:29:21.203 回答
1

在某种Cargo-Cult 编程意义上,您可能会携带一些工件。:-/

例如:我猜**你的 multiplyMatrix 原型上的双重间接(

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

双间接只是一个指向指针的指针。这是一种实现将低级 C 风格的 2D 数组作为参数传递的具体实现点的方法。但是,当您使用碰巧代表矩阵的抽象类时,您不必执行此操作。因此,一旦您将矩阵大小和数据本身封装在 IntegerMatrix 类中,您就不需要这样的东西了:

void printMatrix(IntegerMatrix ** myMatrix);

您更有可能希望传递对封装数据的类的简单引用,如下所示:

void printMatrix(IntegerMatrix const & myMatrix);

实际上,您应该从乘法函数返回一个新矩阵,至少如果您使用它来实现运算符重载...因为从语义上讲,人们编写类似的东西a * b;并对其进行修改是没有意义的 a. (它可以,但你不应该。)所以你可以选择返回一个矩阵值实例:

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

...或返回指向新对象的指针:

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

历史上许多库都选择按指针返回,因为从函数中的局部变量按值返回将涉及在返回时进行复制。返回指针很快(它只“复制”一个 32 位/64 位数字),而复制对象实例和其中的大数据块很慢。所以很多库只会在任何地方使用矩阵指针......问题是很难知道最终delete对象是谁的责任。智能指针是确保这一点的一种方法:

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

但是 C++11 有一些鬼鬼祟祟的能力,可以在没有混乱的情况下保持同样的速度。如果您从函数中按值返回某些内容,并且编译器确定不会再次使用该值(因为它超出了范围),那么它可以像指针一样快地“移动”。这要求您支持RValue 引用的移动构造,其中有各种技巧。

真的有很多细微差别。如果您将此作为一种教育练习,我建议您慢慢来,并阅读一个指导您完成每一步的教程,而不是直接跳入火中。如果您在矩阵中使用低级 C 数组和动态分配,请将它们更改为 a std::vectorof std::vector

于 2012-10-08T19:56:16.697 回答
1

对于IntegerMatrix您使用的一个对象this->table[i][k]来引用您保存矩阵数据的数组,而对于table2对象引用和result指针,您正在使用table2[k][j]and 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;
}
于 2013-04-02T17:29:52.603 回答