void IntArray::
init ( const T *data, int sz)
{
assert( (0 <= sz) && (sz <= MAXINT));
d_num_elements = sz;
if ( 0 == d_num_elements ){ // if no elements in array
d_array = NULL; // array points to NULL
}
else{
d_array = new T [d_num_elements];
}
for (int i=0; i < sz; i++ ){
if ( NULL == data ){
self[i] = T();
}
else{
self[i] = data[i];
}
}
} >assert ( NULL != d_array );
This is a very bad idea for two reasons. First, assert is meant for debugging program errors. Memory allocation failing is not a program error, it's a runtime error that needs to be addressed other than abruptly terminating and giving the user a cryptic error message designed for programmers. Your first assert is good (though an exception would be better, see below), but your second is not. Also, classes should NEVER terminate the program. Throw an exception and have the calling application decide what to do. Finally, new doesn't return a null pointer by default anymore, it throws a bad_alloc exception. Once again, this is something that the calling application needs to handle, so you can just let the exception propagate.
I'll assume that your operator[] checks for d_array being null, otherwise the loop has a bug.