CSE 333 Exercise 10
Due: Wednesday, February 4 by 11 AM
Rating: 3 (note)
Each exercise this quarter is rated on a integer scale of 1 – 5, inclusive, with 1 being the "least time-consuming" and 5 being the "most time-consuming".
This difficulty scale is meant as a rough guide for you in predicting the amount of time to set aside for each exercise as you balance the work required for 333 with your other obligations. However, it is necessarily imperfect as everyone's set of circumstances and experiences with the exercises differ. If your experience with an exercise does not align with its rating, that is not a reflection of you or your abilities.
Goals
- Use dynamic memory allocation in C++ without causing memory leaks.
- Make design decisions about a C++ class, including non-member and friend non-member functions.
- Create a C++ namespace.
- Write a Makefile.
Background
In the previous exercise, you defined a C++ class
Vector that had a lot of functionality.
In this exercise, you will modify how you store the vector data and
add more functionality to your Vector class that
should motivate you to think about C++ class design decisions.
Problem Description
- The member data is stored in a heap-allocated array.
- The lack of getters will change how you organize and implement your methods and non-member functions!
Create a C++ class Vector that implements 3-D vectors
in the following two files.
Vector.h: A header file that declares a classVectorwith the following properties:- The representation of a
Vectorshould be an array containing threedoubles giving the magnitudes in the x, y, and z directions. The array should be dynamically allocated on the heap when aVectoris created and deleted when theVectorno longer exists. - There should be a default (0-argument) constructor that
initializes a
Vectorto (0,0,0), a constructor with 3doubles as parameters giving initial values for the x, y, and z magnitudes (in that order), and a copy constructor. - There should be a destructor that does whatever work is
needed when a
Vectorobject is deleted. If no work is needed, the body of the destructor can be empty. - The class should define assignment on
Vectors (u = v). - The class should define updating assignments on vectors
(
u += vandu -= v) that perform element-by-element addition or subtraction of theVectorcomponents. - Operators
+and-should be overloaded so thatu + vandu - vreturn newVectors that are the sum and difference ofVectorsuandv, respectively. - Operator
*should compute the inner product (i.e., the dot product) of twoVectors as adouble. Ifv1 = (a,b,c)andv2 = (d,e,f), thenv1 * v2should return the scalar valuea*d + b*e + c*f. - Operator
*should also be overloaded so that ifvis the vector(a,b,c)andkis adouble, then BOTHv*kandk*vshould returnVectors containing the components ofvmultiplied byk(i.e.,a*k,b*k,c*k). - Define stream output so that
s << vwill writeVector vto streamsas(a,b,c)(i.e., a left parentheses followed by thex, y, zcomponents ofvseparated by commas (and no spaces), and a right parentheses). - The
Vectorclass and associated functions should be placed in a namespacevector333.
Note that several of these functions are required to return newVectors. This means actualVectorvalues, not pointers toVectors that have been allocated elsewhere.- The representation of a
Vector.cc: A file containing the implementation of theVectorclass.
In addition, you should create the following two files for testing
and compiling your Vector class:
ex10.cc: A file containing amainfunction that tests theVectorobject. More on this in the Implementation Notes below.Makefile: The commandmakeshould compile the source files as needed to create an executable program namedex10. The commandmake cleanshould remove theex10executable file, all.ofiles, and any editor or other backup files whose names end in~(e.g.,ex10.cc~).
Implementation Notes
Getting Started
We recommend referring to: your ex9 solution, the sample ex9 solution, and examples from lecture while implementing this exercise. We also suggest you implement operators and test them one at a time. After everything has been implemented, make a style pass and double-check to see if a function should be member, non-member, or a non-member friend function.
Testing
As opposed to ex9, you do NOT need to explicitly verify the proper
behavior of all of your implemented Vector
functionality in main, though you should still do
proper testing on your own.
We strongly recommend that you write code that tests (1)
cout << v, (2) k*v, and (3)
v*k.
Be sure that if an error is encountered during testing, the testing
code handles it appropriately.
Since there is a significant amount of functionality to test, you
should write static helper functions to factor out redundant code.
Makefile
Your Makefile should contain intermediate .o files for
each .cc file that will be compiled into the
executable.
Your Makefile should also set dependencies correctly such that it
only recompiles individual files and rebuilds the program when
needed, and should reuse any existing .o files or
other files that are already up to date.
Memory Management
Make sure that you use new and delete, as
opposed to their C counterparts.
You should also make sure you follow the best practices for
handling dynamically allocated memory in objects.
In particular, you should make sure that you investigate all
functions related to the rule of three.
Make sure your main function has no memory leaks, even for
non-typical exits (e.g., handling edge cases or test
failures).
We will be using valgrind
(valgrind --leak-check=full ./ex10) to test your code
for memory issues.
Style Focus
Function Access
You will have to decide what functions of the Vector
class to make member functions and which to make non-member
functions.
Some can only be one or the other, while others can be implemented
either way but have stylistic preferences.
This can be one of the more subtle and confusing parts of C++
classes, so be sure to review the related lecture material
carefully!
Friend Functions
In addition to deciding whether a function is a member or
non-member function, you should decide whether a function is
declared as a friend function or not.
Be sure that you only give friend access to non-member
functions that require access to the private members
of the class.
Makefile
Makefiles can be tricky to do correctly while maintaining good style! Things to pay
attention to are having the correct default target and including a cleantarget (discussed above).
Be sure to refer to related lecture material and example Makefiles closely for good
practices.
Submission
Submit the following file(s) by creating an ex10-submit tag in your exercise repository before the assignment deadline. The file(s) should be located in the exact directory listed below, including capitalization:
ex10/Vector.hex10/Vector.ccex10/ex10.ccex10/Makefile
Your code must:
- Compile without errors or warnings on CSE Linux machines
(lab workstations,
attu, or CSE home VM). - Have no runtime errors, memory leaks, or memory errors
(
g++andvalgrind). - Be contained in the files listed above with your Makefile
compiling your code with the
g++options-Wall -g -std=c++17. - Have a comment at the top of your
.ccand.hfiles with your name(s) and CSE or UW email address(es). - Be pretty: the formatting, modularization, variable and
function names, commenting, and so on should be consistent with
class style guidelines.
Additionally, the linter shouldn't have any complaints about your
code (
cpplint.py). - Be robust: your code should deal with hard-to-handle/edge cases and bogus user input (if there are any) gracefully.