Need to help to understand syntax of Constructor call below:
Array::Array( int arraySize )
: size( arraySize > 0 ? arraySize
: throw invalid_argument( "Array size must be greater than 0" ) ),
ptr( new int[ size ] )
{
for ( size_t i = 0; i < size; ++i )
ptr[ i ] = 0; // set pointer-based array element
} // end Array default constructor
// copy constructor for class Array;
// must receive a reference to an Array
Thanks in Advance
#include <iostream>
#include <iomanip>
#include <stdexcept>
#include "Array.h" // Array class definition
usingnamespace std;
// default constructor for class Array (default size 10)
Array::Array( int arraySize )
: size( arraySize > 0 ? arraySize
: throw invalid_argument( "Array size must be greater than 0" ) ),
ptr( newint[ size ] )
{
for ( size_t i = 0; i < size; ++i )
ptr[ i ] = 0; // set pointer-based array element
} // end Array default constructor
// copy constructor for class Array;
// must receive a reference to an Array
Array::Array( const Array &arrayToCopy )
: size( arrayToCopy.size ),
ptr( newint[ size ] )
{
for ( size_t i = 0; i < size; ++i )
ptr[ i ] = arrayToCopy.ptr[ i ]; // copy into object
} // end Array copy constructor
// destructor for class Array
Array::~Array()
{
delete [] ptr; // release pointer-based array space
} // end destructor
// return number of elements of Array
size_t Array::getSize() const
{
return size; // number of elements in Array
} // end function getSize
// overloaded assignment operator;
// const return avoids: ( a1 = a2 ) = a3
const Array &Array::operator=( const Array &right )
{
if ( &right != this ) // avoid self-assignment
{
// for Arrays of different sizes, deallocate original
// left-side Array, then allocate new left-side Array
if ( size != right.size )
{
delete [] ptr; // release space
size = right.size; // resize this object
ptr = newint[ size ]; // create space for Array copy
} // end inner if
for ( size_t i = 0; i < size; ++i )
ptr[ i ] = right.ptr[ i ]; // copy array into object
} // end outer if
return *this; // enables x = y = z, for example
} // end function operator=
// determine if two Arrays are equal and
// return true, otherwise return false
bool Array::operator==( const Array &right ) const
{
if ( size != right.size )
returnfalse; // arrays of different number of elements
for ( size_t i = 0; i < size; ++i )
if ( ptr[ i ] != right.ptr[ i ] )
returnfalse; // Array contents are not equal
returntrue; // Arrays are equal
} // end function operator==
// overloaded subscript operator for non-const Arrays;
// reference return creates a modifiable lvalue
int &Array::operator[]( int subscript )
{
// check for subscript out-of-range error
if ( subscript < 0 || subscript >= size )
throw out_of_range( "Subscript out of range" );
return ptr[ subscript ]; // reference return
} // end function operator[]
// overloaded subscript operator for const Arrays
// const reference return creates an rvalue
int Array::operator[]( int subscript ) const
{
// check for subscript out-of-range error
if ( subscript < 0 || subscript >= size )
throw out_of_range( "Subscript out of range" );
return ptr[ subscript ]; // returns copy of this element
} // end function operator[]
// overloaded input operator for class Array;
// inputs values for entire Array
istream &operator>>( istream &input, Array &a )
{
for ( size_t i = 0; i < a.size; ++i )
input >> a.ptr[ i ];
return input; // enables cin >> x >> y;
} // end function
// overloaded output operator for class Array
ostream &operator<<( ostream &output, const Array &a )
{
// output private ptr-based array
for ( size_t i = 0; i < a.size; ++i )
{
output << setw( 12 ) << a.ptr[ i ];
if ( ( i + 1 ) % 4 == 0 ) // 4 numbers per row of output
output << endl;
} // end for
if ( a.size % 4 != 0 ) // end last line of output
output << endl;
return output; // enables cout << x << y;
} // end function operator<<
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18
// Fig. 10.12: fig10_12.cpp
// Single-argument constructors and implicit conversions.
#include <iostream>
#include "Array.h"
usingnamespace std;
void outputArray( const Array & ); // prototype
int main()
{
Array integers1( 7 ); // 7-element Array
outputArray( integers1 ); // output Array integers1
//outputArray( 3 ); // convert 3 to an Array and output Array’s contents
} // end main
// print Array contents
void outputArray( const Array &arrayToOutput )
{
cout << "The Array received has " << arrayToOutput.getSize()
<< " elements. The contents are:\n" << arrayToOutput << endl;
} // end outputArray
The conditional operator expressions have the form E1 ? E2 : E3
The first operand of the conditional operator is evaluated and contextually converted to bool. After both the value evaluation and all side effects of the first operand are completed, if the result was true, the second operand is evaluated. If the result was false, the third operand is evaluated.
The type and value category of the conditional expression E1 ? E2 : E3 are determined according to the following rules:
1) If either E2 or E3 has type void, then one of the following must be true, or the program is ill-formed:
1.1) Either E2 or E3 (but not both) is a (possibly parenthesized) throw-expression. The result of the conditional operator has the type and the value category of the other expression. ...
... https://en.cppreference.com/w/cpp/language/operator_other#Conditional_operator
Array::Array(int arraySize) :
size(arraySize),
ptr(newint[size])
{
for (size_t i = 0; i < size; ++i)
ptr[i] = 0;
}
Your code is trying to be smarter about how it initializes size (specifically, handle the case where someone passes a number that won't work).
Instead of just passing the size as it comes from the caller, this code is checking to see if the size is usable, and throws an exception if it isn't. To do this, it employs a 'conditional operator expression'. Maybe seeing one on its own will help you figure it out.
1 2 3 4 5 6
int num1 = 1;
int num2 = 1;
// value if conditional is false-----------------+
// value if conditional is true-----+ |
// conditional----------v | |
std::string str = (num1 == num2 ? "equal" : "not equal");
So for your code, instead of initializing "size" with the parameter, it evaluates a conditional operator expression to check the initialization value (shown here on 1 line for clarity):
1 2 3 4 5 6 7
Array::Array(int arraySize) :
size(arraySize > 0 ? arraySize : throw invalid_argument("Array size must be greater than 0")),
ptr(newint[size])
{
for (size_t i = 0; i < size; ++i)
ptr[i] = 0;
}