// This ensures that this file is included at most once // in any program, as there may be multiple include // statements. #pragma once #include #include /////////////////////// // Class declaration // /////////////////////// class Vector_3d; /////////////////////////// // Function declarations // /////////////////////////// // This example extends the previous Vector_3d project by // introducing operator overloading. // // Most of the functions and the Vector_3d class itself are // the same as in the previous project. Refer to that project // for a discussion of the class, inner products, norms, // projections, cross products, normalization, and the use // of const references. // // The focus of this project is operator overloading. C++ // allows us to define the behavior of many operators when // they are applied to objects of a class such as Vector_3d. // // For example, instead of writing // // add( u, v ) // // as in the previous project, we can overload operator+ // so that we can write // // u + v // // instead. The expression is translated into a call to // // operator+( u, v ) // // by the compiler. // // Operator overloading does not create new operators or // change their precedence or associativity. It defines what // an existing C++ operator does when applied to objects of // the specified types. ////// // These query the arguments, but do not change them ////// // Calculate the inner product of u and v. double inner( Vector_3d const &u, Vector_3d const &v ); // Calculate the norm (length) of u. double norm( Vector_3d const &u ); /////////////////////////// // Arithmetic operators // /////////////////////////// // Calculate u + v, instead of using add( u, v ) Vector_3d operator+( Vector_3d const &u, Vector_3d const &v ); // Calculate u - v, instead of using sub( u, v ) Vector_3d operator-( Vector_3d const &u, Vector_3d const &v ); // Calculate a*u for a scalar 'a'. Vector_3d operator*( double const a, Vector_3d const &u ); // Calculate u*a for a scalar 'a'. Vector_3d operator*( Vector_3d const &u, double const a ); // Calculate u/a for a non-zero scalar 'a'. // - There is intentionally no corresponding operator for // 3.0/u, as division of a scalar by a vector is not defined. Vector_3d operator/( Vector_3d const &u, double const a ); /////////////////////// // Unary operators // /////////////////////// // Return u unchanged. // - Here + is a unary operator: it has only one operand. // - This is analogous to applying unary + to a number. Vector_3d operator+( Vector_3d const &u ); // Return the additive inverse -u. // - Notice that this is a different overload from the binary // operator- above. The compiler can distinguish them because // unary - has one argument while binary - has two. Vector_3d operator-( Vector_3d const &u ); ////////////////////////// // Other vector operations ////////////////////////// // Calculate the projection of u onto v. Vector_3d proj( Vector_3d const &u, Vector_3d const &v ); // Calculate the cross product u x v. // // - C++ does not have an existing operator that naturally // represents the vector cross product, so we continue to // use an ordinary function for this operation. Vector_3d cross( Vector_3d const &u, Vector_3d const &v ); /////////////////////////// // Comparison operators // /////////////////////////// // Determine whether u and v are equal using // u == v instead of equal( u, v ) bool operator==( Vector_3d const &u, Vector_3d const &v ); // Determine whether u and v are different using // u != v instead of unequal( u, v ) bool operator!=( Vector_3d const &u, Vector_3d const &v ); /////////////////////////// // Output and conversion // /////////////////////////// // Return a string representation of u. // // This is not an overloaded operator and is unchanged in // principle from the previous project. std::string to_string( Vector_3d const &u ); // Insert a string representation of u into the output stream. // // Overloading operator<< allows us to write // // std::cout << u; // // The first argument is the output stream and the second // argument is the Vector_3d object to be inserted. // // The output stream is returned by reference so that // insertions can be chained: // // std::cout << u << v << std::endl; // // This is the same general mechanism used by the standard // output operations discussed previously. std::ostream &operator<<( std::ostream &out, Vector_3d const &u ); ////////////////////////////////////////////// // These operators modify the first operand // ////////////////////////////////////////////// // Normalize u if it is not the zero vector. // // This remains an ordinary function because there is no // existing C++ operator that naturally represents // normalization. void normalize( Vector_3d &u ); // Add v to u and return u using u += v // - Returning u by reference also allows the result of the // operation to be used as an expression. Vector_3d &operator+=( Vector_3d &u, Vector_3d const &v ); // Subtract v from u and return u using u -= v Vector_3d &operator-=( Vector_3d &u, Vector_3d const &v ); // Multiply u by the scalar a and return u using u *= a. Vector_3d &operator*=( Vector_3d &u, double const a ); // Divide u by the non-zero scalar a and return u using u /= a. Vector_3d &operator/=( Vector_3d &u, double const a ); ////////////////////// // Class definition // ////////////////////// // Store the three components of a 3-dimensional vector. // // This class is unchanged from the previous Vector_3d // project. The important change in this project is how // functions operating on Vector_3d objects are named and // consequently how they can be called. class Vector_3d { public: double x_; double y_; double z_; };