【问题标题】:Overloading operator= doesn't compile with assigning重载 operator= 不能通过赋值编译
【发布时间】:2015-03-06 21:04:34
【问题描述】:

github repo with code 尝试通过重载某些操作来编写 Matrix 类。
当我试图用这个笔画编译时,一切都出错了

result = (l_mtx + r_mtx);

我从 g++ 收到错误:
g++ -g3 -std=c++11 -Wall -o 矩阵 matrix_class.h matrix.cpp

matrix.cpp:在函数“int main()”中:
matrix.cpp:36:12: error: no matching function for call to ‘Matrix::Matrix(Matrix)’

result = (l_mtx + r_mtx);   

然后是这个函数的几个候选人,我不太明白。
我认为有复制构造函数和几个构造函数,但这不是我认为应该在该笔划中调用的 operator=。

matrix_class.h:73:5: 注意:Matrix::Matrix(Matrix&) [with type = double]
(没有已知的参数 1 从“Matrix”到“Matrix&”的转换 )

matrix_class.h:46:5: 注意:Matrix::Matrix(int, int) [with type = double]
(候选人期望 2 个参数,提供 1 个)

matrix_class.h:39:5: 注意:Matrix::Matrix() [with type = double]
(候选人期望 0 个参数,提供 1 个)

然后是错误:
matrix_class.h:96:18: 错误:初始化'Matrix Matrix::operator=(Matrix) [with type = double]'的参数1

我认为我没有正确编码分配运算符或复制构造函数,但我找不到错误在哪里。对不起愚蠢的问题。感谢关注。

//copy constructor
    Matrix(const Matrix<type> &org)
    {
        cout << "Making a copy of " << this << endl;
        row = org.getRow();
        column = org.getColumn();

        //allocate additional space for a copy
        data = new type* [row];
        for (int i = 0; i < row; ++i)
        {
            data[i] = new type [column];
        }

        for (int i = 0; i < row; ++i)
        {
            for (int j = 0; j < column; ++j)
            {
                data[i][j] = org.data[i][j];
            }
        }
    }

和运算符=

//assign constructor
Matrix<type> operator = (Matrix<type> r_mtx)
{
    if (row == r_mtx.getRow())
    {
        if (column == r_mtx.getColumn())
        {
            //TODO: удалить прежний объект?
            Matrix<type> temp(row, column);
            for (int i = 0; i < row; ++i)
            {
                for (int j = 0; j < column; ++j)
                {
                    temp.data[i][j] = r_mtx[i][j];
                }
            }
            return temp;
        }
        else
        {
            cout << "Assign error: matrix column are not equal!" << endl;
            exit(EXIT_FAILURE);
        }
    }
    else
    {
        cout << "Assign error: matrix rows are not equal!" << endl;
        exit(EXIT_FAILURE);
    }
}

【问题讨论】:

  • 您的复制构造函数应该采用const Matrix&amp;
  • 您应该将代码的相关部分复制到您的问题中,而不是链接到外部网站。
  • @Brian 那么我将不允许更改它的字段
  • @Alexander 没错。这是一个副本。它根本不应该修改原件。
  • 如果您有需要在复制时修改的字段,也许您应该声明它们mutable

标签: c++ c++11 matrix


【解决方案1】:

像这样声明复制赋值运算符

Matrix<type> & operator = ( const Matrix<type> &r_mtx )

问题是临时对象可能没有绑定到非常量引用。

考虑到赋值运算符应该返回对左侧对象的引用。

您的赋值运算符本质上是无效的。它不是分配左侧对象,而是创建一个临时对象。所以没有任何分配。

可以这样定义

Matrix<type> & operator = ( const Matrix<type> &r_mtx )
{
    if (row == r_mtx.getRow())
    {
        if (column == r_mtx.getColumn())
        {
            for (int i = 0; i < row; ++i)
            {
                for (int j = 0; j < column; ++j)
                {
                    data[i][j] = r_mtx[i][j];
                }
            }
            return *this;
        }
        else
        {
            cout << "Assign error: matrix column are not equal!" << endl;
            exit(EXIT_FAILURE);
        }
    }
    else
    {
        cout << "Assign error: matrix rows are not equal!" << endl;
        exit(EXIT_FAILURE);
    }
}

【讨论】:

  • 如果我尝试更改此字段,则会出现错误在 'Matrix& Matrix::operator=(const Matrix&) [with type = double ]':matrix.cpp:30:11:此处需要 matrix_class.h:98:17:错误:将 'const Matrix' 作为 'int Matrix::getRow() 的 'this' 参数传递 [ with type = double]' 丢弃限定符 [-fpermissive] if (row == r_mtx.getRow())
  • @Alexander 成员函数 getRow() 和 getColumn() 应使用限定符 const 定义 例如 int getRow() const;
  • @Alexander 在一般意义上,任何不改变对象状态的方法都应该始终是const。这是const 上的good tutorial,何时使用它,以及为什么。
【解决方案2】:

这是一个使用copy and swap idiom 变体的更简单的建议:

Matrix<type> & operator = ( Matrix<type> r_mtx )  //  pass by value
{
    if ( getRow() != r_mtx.getRow() || getColumn() != r_mtx.getColumn() )
        throw std::runtime_error("Wrong dimension in matrix assigment");

    std::swap(data, r_mtx.data);
    return *this;
}

如果您希望即使目标矩阵的大小已经不正确也允许分配,那么您可以取出维度检查,并复制或交换rowcolumn(以及任何其他成员变量)。

使用throw 优于exit,因为它为您的代码的用户提供了更多选择。如果他们不catch那么就相当于退出了。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2014-06-13
    • 1970-01-01
    • 1970-01-01
    • 2018-04-06
    • 2021-07-10
    相关资源
    最近更新 更多