Перегрузка оператора индекса и работа с двойными указателями? - PullRequest
1 голос
/ 08 апреля 2011

У меня есть следующая переменная, с которой мне нужно работать, и я должен написать свою собственную обертку вокруг нее для назначения.Я перехожу за пределы назначения (поскольку мне придется использовать эту оболочку, которую я создаю) и хочу перегрузить оператор индекса в моей оболочке, чтобы использовать его с массивом двойных указателей.В коде я имею в виду следующее:

Что у меня есть:

Из данного заголовка для библиотеки:

typedef struct {        // A pixel stores 3 bytes of data:
    byte red;       //  intensity of the red component
    byte green;     //  intensity of the green component
    byte blue;      //  intensity of the blue component
} pixel;

typedef struct { 
    int   rows, cols;   /* pic size */
    pixel **pixels;     /* image data */
} image;

Мой класс (конечно, включенный в заголовок):

pixels& MyWrapper::operator[] (const int nIndex) {
    return Image.pixels[nIndex]; // where Image is of type image
}

Конечно, это не сработает, поскольку двойной указатель возвращает указатель, который я не советую возвращать, но возвращаю * пиксели и тоже не возвращает.Просто чтобы удовлетворить мое любопытство и помочь мне понять, почему это невозможно, кто-то может сказать мне, как это будет реализовано, если это вообще возможно, и почему это так?Имейте в виду, я пока не очень хорошо понимаю указатели (я знаю основы того, как они работают, но это так), и я надеюсь использовать это, чтобы значительно расширить мое понимание.

Ответы [ 3 ]

1 голос
/ 08 апреля 2011

Неясно, почему вы используете двойное косвенное обращение.

Если pixels - двойной указатель на массив пикселей, вы можете сделать

pixels& MyWrapper::operator[] (const int nIndex) {
    return (*Image.pixels)[nIndex]; // where Image is of type image
}

Если pixels - указатель на массив указателей на массивы, то вам нужно два индекса:

pixels& MyWrapper::operator() ( int xIndex, int yIndex ) {
    return Image.pixels[yIndex][xIndex]; // where Image is of type image
}

Здесь происходит несколько странных вещей.

  • typedef class { } identifier не хорошо C ++. Используйте class identifier { };, иначе у класса нет имени, поэтому вы не можете определять функции-члены вне области действия class { }. (Среди других проблем.)
  • Нет причин делать тип параметра const int. Обычная int выполняет то же самое.
  • Нет очевидной причины двойной косвенности. Обычно в C ++ мы избегаем прямого использования указателей. Вероятно, есть готовая стандартная структура, которую вы можете использовать вместо.
0 голосов
/ 08 апреля 2011

это более типично для c ++:

#include <vector>

namespace AA {

    class t_point {
    public:
        t_point(const size_t& X, const size_t& Y) : d_x(X), d_y(Y) {
        }
       const size_t& x() const { return this->d_x; }
        const size_t& y() const { return this->d_y; }

    private:   
        size_t d_x;
        size_t d_y;
    };

    class t_array {
    public:
        // abusive, but possible. prefer `at`
        const int& operator[](const t_point& idx) const {
            return this->at(idx.x(), idx.y());
        }

        const int& at(const t_point& idx) const {
            return this->at(idx.x(), idx.y());
        }

        const int& at(const size_t& x, const size_t& y) const {
            return this->d_objects[x][y];
        }
    private:
        // or use your c image representation...
        std::vector<std::vector<int> > d_objects;
    private:
        static const int& ctest(const t_array& arr) {
            const t_point pt(1, 2);
            return arr[pt];
            return arr.at(pt);
            return arr.at(pt.d_x, pt.d_y);
        }
    };

}

большая проблема с использованием одного индекса в этом случае заключается в том, что неясно, к какому индексу (пикселю) вы пытаетесь получить доступ, в то время как все вычисления координат отправляются клиенту. если бы это был один указатель, вы бы все равно столкнулись с проблемой на клиенте, но получили бы доступ к индексу предсказуемо.

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

0 голосов
/ 08 апреля 2011

Использование boost :: multi_array

...