Arrays with operator overloading ================================ This example extends the previous Array project by introducing operator overloading. The Array class and the underlying array operations are essentially unchanged. Refer to the previous project for details about dynamic memory allocation, pointers, initialization, clean-up, resetting entries, calculating averages, checking whether entries are sorted, and finding maximum and minimum entries. The focus of this project is on overloading the stream insertion operator << so that Array objects can be sent directly to an output stream. Operator overloading ==================== In the previous project, an Array object could be converted to a string and then displayed using std::cout << to_string( data ); In this project, the << operator is overloaded so that we can instead write std::cout << data; When the compiler encounters std::cout << data it can use the overloaded function operator<<( std::cout, data ) Thus, operator overloading allows an operation involving an object to use familiar C++ notation. Operator overloading does not create new operators, nor does it change the precedence or associativity of existing operators. It defines what an existing operator does when applied to particular types. Output using operator<< ======================= The stream insertion operator has the declaration std::ostream &operator<<( std::ostream &out, Array const &array ); The first argument is the output stream and the second is the Array object to be inserted into that stream. For example, std::cout << data; displays the entries of data enclosed in braces and separated by commas: {3.2, -4.5, 2.1} An empty array is displayed as {} The Array argument is passed by const reference because displaying the array does not modify it. Returning the output stream =========================== The overloaded operator returns the output stream by reference: std::ostream & This allows the result of one insertion to be used immediately by another insertion. For example, std::cout << data << std::endl; can be viewed as a sequence of operations in which each insertion returns the same output stream so that the next insertion can use it. This is the same general mechanism used by the standard << operations for built-in types. operator<< and to_string ======================== The to_string(...) function remains available: to_string( data ) It returns a std::string representation of the Array. The overloaded << operator instead sends the entries directly to the specified output stream. Consequently, we can write std::cout << data; without first creating a string representation. The two operations therefore have related but different purposes: to_string( data ) returns a std::string std::cout << data inserts data into an output stream Operations that remain ordinary functions ========================================== The other Array operations remain ordinary functions: array_init( data, capacity ) array_clean_up( data ) array_reset( data ) average( data ) is_sorted( data ) maxmin( data ) to_string( data ) There is no need to associate these operations with unrelated C++ operators merely because operator overloading is available. Operator overloading should make code clearer and more natural; it should not assign surprising meanings to operators. The Array class =============== The Array class itself is unchanged from the previous project: class Array { public: std::size_t capacity_; double *array_; }; An Array object stores the capacity of a dynamically allocated array and a pointer to its first entry. As in the previous project, an Array object should initially be initialized using Array data{}; before array_init(...) is called. This initializes capacity_ to zero and array_ to nullptr. The important change in this project is not the representation of an Array object, but how an Array object can be used with an output stream. Files ===== Array.hpp Contains the Array class definition and the declarations of the ordinary functions and overloaded operator. Array.cpp Contains the definitions of the Array operations and the overloaded stream insertion operator. Pair.hpp Contains the Pair class used by maxmin(...) to return the indices of the maximum and minimum entries. main.cpp Demonstrates the Array operations and the overloaded stream insertion operator. For additional details about dynamic allocation and the other Array operations, refer to the previous Array project. Compiling ========= Compile both main.cpp and Array.cpp. For example: g++ -std=c++17 -Wall -Wextra -pedantic main.cpp Array.cpp