Thanks JLBorges. That's an ingenious alternative.
I've always felt comfortable with overloading operator[] to go boom, because that's what std::vector would do. We might want some exception safe at() functions though.
Since motez23's assignment has the 2d array derived from a base 1d array object, I thought I'd try building functionality similar to your row object into the 1D array class.
Would you mind giving this a quick sanity check?
In how many ways is this an abomination ?
I added this ctor in the arr1D class for the purpose of supporting operator[] in the derived array2D class.
arr1D( int* pRow, int cols ): pArr(pRow), sz(cols), valid(false) {}
This creates a "dummy" arr1D object with pArr offset to the 1st element of row.
A new
bool valid;
data member is used because pArr != NULL is no longer a sufficient condition for calling delete [] in ~arr1D().
Now
virtual ~arr1D(){ if( valid ) delete [] pArr; }
I also adapted operator= and the copy ctor accordingly.
In the arr1D class I have:
1 2 3 4 5
|
int& operator[]( int index )
{
if( index >= sz ) throw std::out_of_range( "array bounds exceeded" ) ;
return pArr[index];
}
|
In the arr2D class I then have:
1 2 3 4 5
|
arr1D operator[]( int row )
{
if( row >= rows ) throw std::out_of_range( "array bounds exceeded" ) ;
return arr1D(pArr + row*cols, cols);// similar to your row abject
}
|
It does all work, but are there problems with it?
One (specific) question. I wanted the new arr1D ctor to be protected in the arr1D class (do not want user of arr1D creating "dummy" objects), but it wouldn't work (error: arr1D(int*,int) protected in this context. Applies to line 4 in 2nd snippet).
I can use inherited protected data members in arr2D member functions, but not inherited protected functions? Guess I better review the basics.