Explain Syntax Constructor call

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

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
#define ARRAY_H
#include <iostream>
class Array
{
friend std::ostream &operator<<( std::ostream &, const Array & );
friend std::istream &operator>>( std::istream &, Array & );
public:
explicit Array( int = 10 ); // default constructor
Array( const Array & ); // copy constructor
~Array(); // destructor
size_t getSize() const; // return size
const Array &operator=( const Array & ); // assignment operator
bool operator==( const Array & ) const; // equality operator

// inequality operator; returns opposite of == operator
bool operator!=( const Array &right ) const
{
return ! ( *this == right ); // invokes Array::operator==
} // end function operator!=
// subscript operator for non-const objects returns modifiable lvalue
int &operator[]( int );
// subscript operator for const objects returns rvalue
int operator[]( int ) const;
private:
size_t size; // pointer-based array size
int *ptr; // pointer to first element of pointer-based array
}; // end class Array 


1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
#include <iostream>
#include <iomanip>
#include <stdexcept>
#include "Array.h" // Array class definition
using namespace 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( 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
Array::Array( const Array &arrayToCopy )
: size( arrayToCopy.size ),
ptr( new int[ 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 = new int[ 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 )
return false; // arrays of different number of elements
for ( size_t i = 0; i < size; ++i )
if ( ptr[ i ] != right.ptr[ i ] )
return false; // Array contents are not equal
return true; // 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"
using namespace 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
shouldn't it be able to initialize the memory without the explicit loop?
Still can not get:
ArraySize > 0 => True
Then compiler does what?
I see only this way:
if E1 is true
compiler calls:
ArraySize : ptr(new int[size])

But i can not remember this syntax


Last edited on
You understand this syntax, correct?
1
2
3
4
5
6
7
Array::Array(int arraySize) :
    size(arraySize),
    ptr(new int[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(new int[size])
{
    for (size_t i = 0; i < size; ++i)
        ptr[i] = 0;
}
Last edited on
Seems clear now! Thanks
Array::Array( const Array &arrayToCopy )
: size( arrayToCopy.size ), [1]
ptr( new int[ size ] ) [2]

first part of this construction is still not 100% clear

probably it works like
size = arrayToCopy[*objectVariableOnEntry_or_defaultIntFromConstructorDefinition]

Big thanks in advance
Topic archived. No new replies allowed.