【问题标题】:can not send const value to operator+ that use operator[][]无法将 const 值发送到使用 operator[][] 的 operator+
【发布时间】:2014-01-24 09:16:42
【问题描述】:

我想实现一个使用运算符 [][] 的矩阵类。

我编写了以下代码,但问题是我无法将 const 值发送给 operator+ !!(错误:将 'const Matrix' 作为 'Matrix::Indexer Matrix 的 'this' 参数传递: :operator' 丢弃限定符 [-fpermissive])

如果我把它改成 Matrix operator+(Matrix& other);它工作正常...

我想我需要两个重载的 Matrix::Indexer Matrix::operator[](int index) 一个用于读取,一个用于写入 mat_ (就像 c# 中的属性!)但是如何?!

或者我应该使用 const_cast 吗?!

实现这个类的最好方法是什么?!

//Matrix.h 
class Matrix
{
public:
    Matrix(const int rows, const int cols, float defaultValue=0);
    //TODO copy constructor , destructor

    int rows() const;
    int cols() const;


    Matrix operator+(const Matrix& other);

    class Indexer
    {
    public:
        Indexer(float* arr,int cols);
        float& operator[](int index);
    private:
        float* arr_;
        int cols_;
    };

    Indexer operator[](int index);

private:
    int rows_;
    int cols_;
    float **mat_;

};

矩阵.cpp

#include "matrix.h"

Matrix::Matrix(const int rows, const int cols, float defaultValue) :
    rows_(rows),
    cols_(cols)
{
    mat_=new float*[rows_];

    for(int i=0;i<rows;i++)
    {
        mat_[i]=new float[cols];
    }

    for(int i=0;i<rows;i++)
    {
        for(int j=0;j<cols;j++)
        {
            mat_[i][j]=defaultValue;
        }
    }

}


int Matrix::rows() const
{
    return rows_;
}
int Matrix::cols() const
{
    return cols_;
}


Matrix::Indexer::Indexer(float* arr,int cols):
    arr_(arr),
    cols_(cols)
{}


Matrix::Indexer Matrix::operator[](int index)
{
    if(index>=rows_)
        throw "Out of row index";
    return Indexer(mat_[index],cols_);
}

float& Matrix::Indexer::operator[](int index)
{
    if(index>=cols_)
       throw "Out of cols index";
    return arr_[index];
}

 Matrix Matrix::operator+(const Matrix& other)//error
 {
     if(other.rows()!=this->rows()||other.cols()!=this->cols())
         throw "rows and cols are not equal";
     Matrix result(other.rows(),other.cols());
     for(int i=0;i<rows();i++)
     {
         for(int j=0;j<cols();j++)
         {
             result[i][j]=mat_[i][j]+other[i][j];//error: passing 'const Matrix' as 'this' argument of 'Matrix::Indexer Matrix::operator' discards qualifiers [-fpermissive
         }

     }
     return result;
 }

【问题讨论】:

  • @BrettHale 是的。在我们的代码中,矩阵上的[] 返回一个Row,它本身不包含任何数据,但提供了矩阵数据子集的视图。 (我们也有一个列视图,但这可能很难实现。)
  • @BrettHale 矩阵仍然是行优先的。 RowColumn 都提供矩阵的视图(投影)。
  • @BrettHale 除了这没有什么是主要的专栏。对于 n 维数据结构,在单个维度上(至少)有 n 个投影。提供一个而不提供所有这些是缺乏正交性,至少可以这么说。

标签: c++ operator-overloading


【解决方案1】:

您的operator+ 应该是一个 const 成员函数,因为它不会修改调用它的对象。对于其余部分,您可能还需要 ConstIndexeroperator[]( int index ) const

与您的问题完全无关,但是:您最好使用std::vector&lt;float&gt; 来获取实际数据。它更易于使用,而且(可能)更快。

【讨论】:

    【解决方案2】:

    我通过添加解决了我的问题

    const Indexer operator[](int index)const;
    

    const float& operator[](int index)const;
    

    我的代码:

    Matrix.h

    #ifndef MATRIX_H
    #define MATRIX_H
    
    #include <iostream>
    
    class Matrix
    {
    public:
        Matrix(const int rows, const int cols, float defaultValue=0);
        //TODO copy constructor , destructor
    
        int rows() const;
        int cols() const;
    
    
        Matrix operator+(const Matrix& other) const;
    
        class Indexer
        {
        public:
            Indexer(float* arr,int cols);
            const float& operator[](int index)const;
            float& operator[](int index);
        private:
            float* arr_;
            int cols_;
        };
    
        Indexer operator[](int index);
        const Indexer operator[](int index)const;
    
        friend std::ostream& operator<<(std::ostream& os,const Matrix& m);
    
    private:
        int rows_;
        int cols_;
        float **mat_;
    };
    
    #endif // MATRIX_H
    

    Matrix.cpp

    #include "matrix.h"
    
    Matrix::Matrix(const int rows, const int cols, float defaultValue) :
        rows_(rows),
        cols_(cols)
    {
        mat_=new float*[rows_];
    
        for(int i=0;i<rows;i++)
        {
            mat_[i]=new float[cols];
        }
    
        for(int i=0;i<rows;i++)
        {
            for(int j=0;j<cols;j++)
            {
                mat_[i][j]=defaultValue;
            }
        }
    
    }
    
    
    int Matrix::rows() const
    {
        return rows_;
    }
    int Matrix::cols() const
    {
        return cols_;
    }
    
    
    Matrix::Indexer::Indexer(float* arr,int cols):
        arr_(arr),
        cols_(cols)
    {}
    
    const float &Matrix::Indexer::operator[](int index) const
    {
        if(index>=cols_)
           throw "Out of cols index";
        return arr_[index];
    }
    
    
    Matrix::Indexer Matrix::operator[](int index)
    {
        if(index>=rows_)
            throw "Out of row index";
        return Indexer(mat_[index],cols_);
    }
    
    const Matrix::Indexer Matrix::operator[](int index) const
    {
        if(index>=rows_)
            throw "Out of row index";
        return Indexer(mat_[index],cols_);
    }
    
    std::ostream& operator<<(std::ostream &os, const Matrix &m)
    {
        for(int i=0;i<m.rows();i++)
        {
            for(int j=0;j<m.cols();j++)
            {
                os<<m[i][j]<<" ";
            }
            os<<"\n";
        }
        return os;
    }
    
    float& Matrix::Indexer::operator[](int index)
    {
        if(index>=cols_)
           throw "Out of cols index";
        return arr_[index];
    }
    
     Matrix Matrix::operator+(const Matrix& other) const
     {
         if(other.rows()!=this->rows()||other.cols()!=this->cols())
             throw "rows and cols are not equal";
         Matrix result(other.rows(),other.cols());
         for(int i=0;i<rows();i++)
         {
             for(int j=0;j<cols();j++)
             {
                 result[i][j]=mat_[i][j]+other[i][j];
             }
    
         }
         return result;
     }
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2021-12-01
      • 2018-07-30
      • 1970-01-01
      相关资源
      最近更新 更多