2

I have the following variable that I need to work with, and have to write my own wrapper around it for an assignment. I am going beyond the assignment (since I am going to have to use this wrapper I make) and wanting to overload the subscript operator in my wrapper in order to use it with the double pointer array. What I mean in code is this:

What I have:

From given header for library:

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;

My class (of course included in header):

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

Of course this won't work since the double pointer returns a pointer, which is not what I'm telling it to return, yet returning *pixels& doesn't return it either. Just to sate my curiosity and to help me understand why this isn't possible, could someone tell me how this would be implemented if it can be at all, and why it is that way? Keep in mind I don't understand pointers very well yet (I know of the basics of how they work, but thats it), and am hoping to use this to very much broaden my understanding.

2
  • ... Umm... should you try pixels*& instead? Commented Apr 8, 2011 at 7:20
  • ...Or just return pixel* as an array of pixel, and use [] on that? Commented Apr 8, 2011 at 10:50

3 Answers 3

2

this is more typical, for 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);
        }
    };

}

the big problem with using one index in this case it that it is not clear which index (pixel) you are attempting to access, while pushing all the coordinate calculations off to the client. if it's a single pointer, you'd still push the problem onto the client, but you'd be able access the index predictably.

with double... the layout in memory can vary, it is not necessarily contiguous. it's just a bad design to publish it as a single value (logically, as a 1D array), rather than a 2D array or a point (for example).

Sign up to request clarification or add additional context in comments.

2 Comments

I have no control over the library and can't use that, I'm forced to have to work with the double pointer, whih is why I asked.
ok. the syntax will be the same as written op[] and at. using this c interface, you'll have to add your own logic for bounds checking, memory management, copying, constructing with offsets, coordinate offsets (where applicable) and so on. the subscript notation just functions as a multiply by the element offsets by the index you desire. the first will determine the address of either a row or column of pixels, then second will return then apply another offset for the pixel in the row or column.
1

It's not clear why you are using double indirection in the first place.

If pixels is a double pointer to an array of pixels, you can do

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

If pixels is a pointer to an array of pointers to arrays, then you need two indices:

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

There are a few weird things going on here.

  • typedef class { } identifier is not good C++. Use class identifier { };, or else the class has no name, so you cannot define member functions outside the class { } scope. (Among other problems.)
  • There is no reason to make a parameter type const int. Plain int accomplishes the same thing.
  • There is no apparent reason for the double indirection. Typically in C++ we avoid the direct use of pointers. There is probably a prepackaged standard structure you can use instead.

3 Comments

When using multiple indices, operator() should be preferred over operator[]. The latter would only work with a pair or similar structure.
@Tad: I just wasn't paying enough attention :vP .
You're right, that second overload is the correct one. Thanks.
-1

Use boost::multi_array

1 Comment

I have no control over the library and can't use that, I'm forced to have to work with the double pointer, whih is why I asked.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.