Как перегрузить оператор [] в C ++?

0

У меня есть некоторые проблемы для перегрузки operator [] в C++ для матрицы. Скажем, что в моей Class Matrix меня есть matrix m[2][2] 2X2 matrix m[2][2] Какой код должен выглядеть, если я хочу позвонить элемент из массива m[1][1] вместо object.m[1][1]? Я думаю, заголовок должен быть чем-то вроде int operator[] (const int) но я не знаю, как его построить... Если кто-то может мне помочь, спасибо заранее.

  • 3
    Я бы рекомендовал придерживаться m(1, 1) .
  • 0
    @chris, дополнительное объяснение для начинающего было бы очень желательно
Показать ещё 3 комментария
Теги:
operators
matrix
overloading

2 ответа

5

Существует два решения. Во-первых, как предлагает @chris, вы можете использовать operator()( int i, int j ); многие математически ориентированные люди даже предпочитают это. В противном случае operator[] должен вернуть прокси; тип, на котором также определен [], к которому может применяться второй [], чтобы возвращать правильные результаты. Для двухмерных структур простейший прокси - это просто указатель на строку, так как [] определен для указателей. Но часто бывает предпочтительнее возвращать полный тип класса, чтобы выполнять проверку ошибок. Что-то вроде:

template <typename T>
Matrix2D
{
    int myRowCount;
    int myColumnCount;
    std::vector<T> myData;
public:
    T& getRef( int i, int j )
    {
        return myData[ i * myRowCount +  j ];
    }

    class Proxy
    {
        Matrix2D* myOwner;
        int myRowIndex;
    public:
        Proxy( Matrix2D* owner, int i )
            : myOwner( owner )
            , myRowIndex( i )
        {
        }

        T& operator[]( int j )
        {
            return myOwner->getRef( myRowIndex, j );
        }
    };

    Proxy operator[]( int i )
    {
        return Proxy( this, i );
    }
};

Вероятно, вам понадобится также версия const для прокси, чтобы перегрузить [] на const.

Для версии () просто замените getRef на operator() (буквально) и getRef Proxy и operator[].

  • 0
    Большое спасибо. Я реализовал «@» решение @chris, и оно отлично работает. Я никогда не думал об использовании () вместо [].
  • 0
    @ user3187893 Оба решения работают хорошо. Это вопрос пользовательских предпочтений. Здесь мы также используем решение @chris, и пользователи, кажется, довольны им; но в тех местах, где я работал ранее, решение по доверенности (и m[i][j] ) было предпочтительным.
Показать ещё 1 комментарий
1

Вот пример того, как оператор [] может быть реализован для класса с двумерным массивом. Попробуйте, и вы будете удовлетворены. :)

Вам не потребуется ни прокси, ни составная операторская функция.

#include <iostream>

int main()
{
    struct A
    {
        int a[10][10];
        int ( & operator []( int n ) )[10]
        {
            return ( a[n] );
        }
    };

    A a;

    for ( int i = 0; i < 10; i++ )
    {
        for ( int j = 0; j < 10; j++ )
        {
            a[i][j] = 10 * i + j;
        }
    }

    for ( int i = 0; i < 10; i++ )
    {
        for ( int j = 0; j < 10; j++ )
        {
            std::cout << a.a[i][j] << ' ';
        }
        std::cout << std::endl;
    }
}
  • 0
    Ух ты. Это заявление operator[] заставляет мою голову болеть. Если есть кто - нибудь еще , для кого он не нажимал сразу, как объявить ссылочный a в массив 10 int s в C ++ это с немного нечетным синтаксиса int (&a)[10] . Этот пример имеет еще один шаг вперед, и заменяет с a operator[](int n) (т.е. оператор возвращает ссылку на Int массив размера 10). Это законно, это работает, и это, конечно, умно, но я не уверен, что я чувствую по этому поводу ...

Ещё вопросы

Сообщество Overcoder
Наверх
Меню