views:

234

answers:

5

I have an assignment from my programming class, which is very poorly worded... The following line really stumps me. We're creating a class called FloatArray, which contains an array (arr, which is just a pointer to a bunch of floats).

The default constructor FloatArray(); should create array of zero width and zero height.

I have no clue what my professor means by that... Does anyone else? We're required to provide another constructor, which indicates the height and width of the array. That's fine and dandy - just plug in the numbers, and allocate away... But what does he mean by "create array of zero width and zero height"?

Just so you know, the array is simply defined as:

float *arr;

Help me understand this madness! If it were up to me, I wouldn't even make a blank constructor for such a class...

Regardless - am I overlooking something here? Is this some kind of terminology I've never encountered before, or am I correct in stating that this is madness?

Should I just do the following in the default constuctor?

*arr = 0;

Because I can't do arr = new float[0], now can I :P (Or maybe I can - I just tried it (thanks Thomas!) and it compiles and runs... !?)

Does this mean that when I do arr = new float[0], arr points to some location (the beginning?) on the heap?

I know this question seems quite vague, but that's how the entire assignment is - very poorly worded. I just want to make sure it's not just me!

+1  A: 

You should ask your professor. I doubt he will see this here. He might just mean to initialize it to null.

jdelator
Isn't it initialized to null when you define the pointer in the first place, though?
Breakthrough
It will depend on the language or environment. Some languages, like C#, are specified so that variables are initialised when they are declared. Others, like C++, aren't but the IDE you use might do it for you.
ChrisF
+2  A: 

I think he means that the constructor should not initialize any memory space for the array.

Nevertheless ask your professor.

Cristina
+6  A: 

This exercise may be intended to highlight the difference between interface and representation. I don't know what the other methods in the FloatArray class are supposed to be, but I suspect there are methods to get and set elements in particular positions of the array.

With such a default constructor, the class should create an object that acts as if it has zero width and zero height. That is, if the caller then requests to set a particular element of the array, then the method should return whatever condition it normally would for "out of bounds". That is, by throwing an exception or an error return or whatever.

Internally, the class can represent this condition however it likes, even by allocating memory. Maybe it's sufficient to set arr = NULL, or maybe it has to point to non-null memory, but that's up to you as the implementor of the class. The point is the interface should act in a particular way as defined by the assignment question.

Greg Hewgill
Actually, to reference individual elements in the array (which is single dimensional, but we are displaying it to "the programmer" as two-dimensional), so the [] operator is overloaded to return a position shifted by the "height" of the array [x] x times over.
Breakthrough
I don't like the way this assignment is set up, put it this way - a lot of arbitrary, unnecessary steps to accomplish something VERY simple.I'm not the prof though!
Breakthrough
If you believe that a step is arbitrary or unnecessary, *ask* your instructor about it. Either it really is unnecessary, or it is intended to highlight some aspect of the problem at hand. Or perhaps it's there to set the foundation for later exercises.
Greg Hewgill
Put it this way, Greg. Would you rather just declare a multidimensional array, or would you rather declare a single-dimensional array, and overload the [] operator so that the object itself "looks" like a multidimensional array?
Breakthrough
In C++, you can't declare a multidimensional array that has both dimensions variable. So you're going to have to do the latter.
Greg Hewgill
Greg - you can just declare the first dimension, then use a for-loop to go through every element in that dimension, and in-turn, fill that with another array.
Breakthrough
Yes, but that's not a two-dimensional array. That's an array of arrays, which is subtly different. In particular, a two-dimensional array has rows that are always guaranteed to be the same length. An array of arrays may have different length arrays in each row.
Greg Hewgill
The term "array of array" for `T*[N]` or `T**` seems to come from other languages. I find this difference to make not really helpful in C, where `T[N][M]` is in fact an "array of arrays", since it's equivalent to `typedef T Mt[M]; Mt[N]`. "Array of arrays" and "multi-dimensional arrays" is one and the same thing - actually the latter term is just a common name for the former. A better term for `T*[N]` and `T**` is, i think, "array of pointer to arrays", which makes clear that the next dimension is really not a sub-array, but points to a possibly different sized array.
Johannes Schaub - litb
+1  A: 

Doing *arr = 0 in the constructor would be very unwise. Since arr is uninitialized it might point to anything. Therefor *arr = 0 means "set some random memoryblock to 0 which probably will fail. On the other hand, doing arr = new float[0] is indeed a valid operation.

I would recommend using a "new float[0]" for 0-size arrays. This reduces some special handling of 0-size arrays, such as arrays explicitly created using new FloatArray(0) which should result in the exact same array as new FloatArray(). Note that a good alternative may be to have a default zero-value of the length argument in the "regular" constructor.

larsm
A: 

You might want something like this:

#include <exception>

class FloatArray 
{
public:
    FloatArray():arr(new float[0]){}
    FloatArray(int width, int height)
    {
     arr=new float[height*width];
     mWidth=width;
     mHeight=height;
    }

    ~FloatArray(){ delete [] arr; }

    float operator()(int xindex, int yindex)
    {
     if (!isValid(xindex,yindex))
     {
      throw std::exception();  // Some suitable exception
     }
     return arr[yindex*mWidth+xindex];
    }

    bool isValid(int xindex, int yindex);

private:
    float* arr;
    int mWidth;
    int mHeight;
};

Points to note:
I've left isValid() without a definition as an exercise.
The dtor is fine with EDIT: delete [] arr; whichever ctor was called.
I've used operator() as the accessor.
You could throw something else apart from std::exception.
There are no setter methods - left as an exercise.
I've put in one deliberate error that I know of.

quamrana
Would the error be "delete arr;" which should be "delete[] arr;" ?
Breakthrough
Oops - OK, I was sure that someone would find another error. Well, maybe that was what your prof was saying - you need one dtor which will have to be `delete[] arr;` therefore you need `arr=new float[0];` in the default dtor. See my edit.
quamrana