Операторы класса - PullRequest
       2

Операторы класса

0 голосов
/ 28 декабря 2018

У меня проблема с созданием кода:

void main(){
     Matrix c(rows,cols);//rows & cols are int numbers
     c[0][0]=2//the line that I'm having a problem to do the operator
}

//My class defined like this: 
class Matrix{
public:
     Matrix(int rows,int cols): rows(rows), cols(cols){
         mat= new double*[cols];
         for( int i=0; i<rows;i++){
             *mat=new double[i];
         }
     }
private:
     int rows,cols;
     double **mat;
};

Как я могу сделать оператор, который поможет мне выполнить строку, с которой у меня проблема?

Ответы [ 2 ]

0 голосов
/ 28 декабря 2018

Не выделяйте динамически в двух измерениях, как это.Это яд для вашего кеша и совершенно бессмысленный .Я вижу это все время и я бы не хотел!Вместо этого сделайте себе std::vector<double> размера rows*cols.

В любом случае, уловка, позволяющая [width][height], - это прокси-класс .Пусть ваш operator[] вернет экземпляр класса, который имеет собственный operator[] для выполнения поиска второго уровня.

Примерно так:

#include <iostream>
#include <vector>

struct Matrix
{
    Matrix(const size_t columns, const size_t rows)
       : columns(columns)
       , rows(rows)
       , data(columns*rows, 0)
    {}

    size_t index(const size_t x, const size_t y) const
    {
        return x + y*columns;
    }

    double& at(const size_t x, const size_t y)
    {
        return data[index(x, y)];
    }

    double at(const size_t x, const size_t y) const
    {
        return data[index(x, y)];
    }

    template <bool Const>
    struct LookupHelper
    {
        using ParentType = std::conditional_t<Const, const Matrix, Matrix>;
        using ReturnType = std::conditional_t<Const, double, double&>;

        LookupHelper(ParentType& parent, const size_t x) : parent(parent), x(x) {}

        ReturnType operator[](const size_t y)
        {
            return parent.data[parent.index(x, y)];
        }

        const ReturnType operator[](const size_t y) const
        {
            return parent.data[parent.index(x, y)];
        }

    private:
        ParentType& parent;
        const size_t x;
    };

    LookupHelper<false> operator[](const size_t x)
    {
        return {*this, x};
    }

    LookupHelper<true> operator[](const size_t x) const
    {
        return {*this, x};
    }

private:
    const size_t columns, rows;
    std::vector<double> data;
};

int main()
{
    Matrix m(42, 3);
    m[15][3] = 1;
    std::cout << m[15][3] << '\n';
}

(Вна самом деле, вы бы хотели сделать его подвижным, и, несомненно, его можно немного привести в порядок.)

Конечно, переключается на operator() или a .at(width, height) функция-член намного проще ...

0 голосов
/ 28 декабря 2018

Нет operator [][], но operator[].Так что нужно возвращать что-то, для чего вы тоже можете использовать [] (указатель или прокси-класс).

В вашем случае вы можете просто сделать:

double* operator[](int i) { return mat[i]; }
const double* operator[](int i) const { return mat[i]; }

Для более сложных случаев, вы должны вернуть прокси-класс.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...