(C++)使用具有 const 引用参数的多个运算符重载 [duplicate]

(C++) Using multiple operator overloads with const reference parameters [duplicate]

提问人:AssistantToTheRegionalManager 提问时间:7/2/2022 最后编辑:Vlad from MoscowAssistantToTheRegionalManager 更新时间:7/2/2022 访问量:86

问:

我一直在研究一个矩阵类,最近我学会了如何将常量引用传递给运算符重载,这样我就可以在同一行上有多个引用。我遇到的问题是在为运算符重载定义函数时,该函数通过常量引用获取参数,然后尝试对该参数使用另一个运算符重载。下面显示了一些最小的代码:

class Matrix
{
private:
    int col, row;
    typedef std::vector<double> Column;
    std::vector<Column> data;
public:
    Matrix(int rows, int columns) : col(columns), row(rows), data(rows, std::vector<double>(columns))
    {}

    Column& operator[](int i) //Operator overload to allow for use of Matrix[i][j]
    {
        return data[i];
    }

    Matrix& operator*(const Matrix& matrix2)
    {
        Matrix* matrix1 = new Matrix(row, col);
        matrix1->data = this->data;
        double tempValue = matrix1[0][0] * matrix2[0][0]; //Error here when accessing matrix2[0][0]

        return *matrix1;
    }
};

正如您在 operator* 代码中看到的,我正在尝试使用 [] 运算符的重载,这通常可以帮助我使用 matrix[i][j] 表示法来枚举其数据。在我开始使用 const Matrix& 作为要传递的参数之前,这一直工作正常。现在,当尝试访问 matrix2 的索引时,它给了我这个错误:

没有运算符“[]”与这些操作数匹配

有谁知道为什么会发生这种情况或如何解决它?我尝试使用 const int& 作为运算符 [] 重载的参数,但似乎没有帮助。否则,访问 matrix1 的索引似乎可以正常工作。

C++ 运算符重载 pass-by-const-reference

评论

1赞 Pepijn Kramer 7/2/2022
你的列类是否也实现了运算符[]?在运算符*中,不要新建你的返回值,返回一个矩阵而不是一个矩阵*!如果需要分配内存,请避免在C++中新增/删除,如果需要分配内存,请使用 std::make_unique(或 std::make_shared)
2赞 Some programmer dude 7/2/2022
我推荐了这个规范的实现运算符重载指南

答:

1赞 Vlad from Moscow 7/2/2022 #1

对于初学者来说,是一个指针,但您需要为以下类型的对象应用下标运算符。matrix1Matrix

matrix2是一个常量对象,但下标运算符不是常量成员函数。

您需要将运算符 [] 重载为常量成员函数

Column& operator[](int i) //Operator overload to allow for use of Matrix[i][j]
{
    return data[i];
}

const Column& operator[](int i) const //Operator overload to allow for use of Matrix[i][j]
{
    return data[i];
}

运算符 * 应该声明为

Matrix operator*(const Matrix& matrix2) const
{
    Matrix matrix1(row, col);
    matrix1.data = this->data;
    double tempValue = matrix1[0][0] * matrix2[0][0];

    return matrix1;
}

虽然目前尚不清楚这种说法是什么

    double tempValue = matrix1[0][0] * matrix2[0][0];

正在这里做:)

请注意,在运算符 * 中动态分配对象是一个非常糟糕的主意。

评论

0赞 AssistantToTheRegionalManager 7/2/2022
我在这里遇到的问题是,如果我按 * 运算符的值返回 matrix1,我将无法在不分配给中间变量的情况下在一行上使用其中的几个运算符。例如,除非 * 运算符通过引用返回矩阵对象,否则 Matrix matrix = matrix1 * matrix2 * matrix3 将不起作用。顺便说一句,tempValue 语句没有做任何功能,我剥离了该函数以仅显示遇到错误的位置,它实际上循环索引并执行标准矩阵乘法。
1赞 Vlad from Moscow 7/2/2022
@AssistantToTheRegionalManager 你错了。您可以将临时对象绑定到常量引用。如果你进行我展示的更改,你将能够编写例如矩阵 m1( 2, 2 );矩阵 m2 = m1 * 矩阵( 2, 2 ) * 矩阵( 2, 2 );
1赞 Vlad from Moscow 7/2/2022
@AssistantToTheRegionalManager 引用应由赋值运算符或下标运算符返回,至少不是常量成员函数。
1赞 Vlad from Moscow 7/2/2022
@AssistantToTheRegionalManager 您可以将临时对象绑定到常量左值引用。因此,您可以将临时对象传递给具有相应参数作为常量引用的函数,并且在执行函数时,临时对象将处于活动状态。
1赞 Vlad from Moscow 7/2/2022
@AssistantToTheRegionalManager 正如我在回答中所示,您需要有两个重载运算符。