I've been digging around and I'm having trouble figuring this one out on my own. In my program I have a class that contains a 2 dimensional array and some information and routines regarding the array. I'd like to declare the array as a variable length array (i.e. myArray[xDim][yDim] rather than myArray[12][12]) so that I may have the dimensions as a parameter at the beginning of my program. It doesn't need to be dynamic since it won't change throughout the program, but I have no trouble with this sort of thing outside of classes. I just make the variable a const int and it's all good (i.e. const int xDim = 12; myArray[xDim][xDim]). Declaring a member variable of my class const means I can't set it through a constructor, so my usual method won't work here. I did get this to work:
But this has the unfortunate effect of losing out of bounds checking. If someone tried to access hmod.data[12] they'll get garbage instead of a seg fault. I have qualms with #define (has to be implementation header file) and declaring a global (globals are icky).
Is there another way to set the size with the constructor? Something along the lines of:
Do you mean overload the [ ] operator to do bounds checking on pointers? How would I go about that exactly? I'm not sure where I would check to get the length since it would be different for different instantiations of the class.
What you'd do is create a new data member that keeps track of the current amount of elements within the allocated array. Using this data member, you can perform index validation checks. For example:
1 2 3 4 5 6 7 8 9 10 11 12 13 14
class block
{
...
unsignedint TotalElements;
int *data; // Allocated elsewhere.
int *operator [ ] ( constunsignedint Index )
{
if( ( Index >= 0 ) && ( Index <= ( TotalElements - 1 ) ) )
return &data[ Index ];
elsereturnnullptr;
}
};
class block
{
...
unsignedint TotalElements;
int *data; // Allocated elsewhere.
int& operator [ ] ( unsignedint Index )
{
staticint s_invalidElem = 0;
if( Index < TotalElements )
return data[ Index ];
}
return s_invalidElem;
};
Notes
- There no need for 0 <= test as the index is unsigned
- <= x - 1 is the same as < x
- no need for const when passing param by value
- I would probably define a const version of method as well
- You could stick an assert in for the debug build
Thanks, that helps somewhat, but I'm looking for another approach to passing in a constant for the dimension of the member array if there is one. I've been playing around with this pointer/new method some more and noticed a couple more limitations (if not with the method, then with my skills :P).
1) In my program the array will actually be 2 dimensional. new doesn't make a 2 dimensional array.
2) This class is going to be implemented with an array of the class. I'm not sure how to pass in the dimension when declaring the array of blocks.
I assume you're doing this as a programming exercise? If so, it's easy enough to do with a one dimensional array and a bit of arithmatic.
I would just define getAt(x,y) and setAt(x,y,value) member for your class. With a bit more work you can get the class to act like a normal 2D array, but it's not going to simplify the classes use that much. So unless you want a little programming challenge.
There are plenty of solutions to this problem on the net. So once you have your version working, you could compare it with other peoples.
I'm not sure I get your second question. std::vector's size can be declared either when it's constructed or by calling resize(). You could follow the same approach.
I'm doing this as part of an internship rewriting a simulation for parallel use. Basically, I have an existing block class that has a member array that's hard coded to 12x12 at the moment. I want to generalize it to an nxn array. Rewriting it using dynamic allocation seems to require more and more time as I look into it. Plus it's overkill. The array dimension will be a parameter at the beginning of the code with the rest. It will be known at compile time and it will not change throughout the execution of the program.
Normally declaring a constant sized array like this: