CS510_CW12_Nengyin & Kaiqin

Examine the source code in src/structs carefully.

i. Explain how this code differs from the equivalent C implementation that you examined in a previous class. Be specific and detailed.

  1. In C++ header file, there is #ifndef and #endif to start and end of the header file; C does not have them. It can avoid falling into the infinite loop of calling header and source files by each other. (hope I understand correctly)
  2. In C++ header file, there is "#define guard" to ensure that the header file is only included once by the preprocessor; In C there is some unit testing frameworks for similar usage.
  3. In C++, struct has a typedef defined automatically. But in C, we must declare and alias a new struct type before use.
  4. In C, it is usually by convention to capitalize all letters for self-defined types or structures. Now in C++, it seems that we only need to capitalize the first letter.
  5. Pass-by-reference in C++ can write as "Vec2 &wp", and its fields are accessible by "wp.x". It looks just like pass-by-value, but the original memory location does alter. In C, pass-by-reference writes as a pointer "Vec2 *wp".
  6. Function overloading allows the same name to be used for different types, which does not work in C.
  7. Operator definition is new in C++ and is convenient.

ii. Explain what a #define guard does, and why it could be useful.

It used to ensure the header file is only included once by the preprocessor. Thus avoid the second definition of objects, like struct, type, functions and so on. So that the program can compile correctly.

// From: https://en.wikipedia.org/wiki/Include_guard

iii. Explain what type overloading is, and why it could be useful.

It defines both operator and function overloading, which is the same name but different types or different numbers of arguments, but only return type different doesn't work. It is useful because you can have multiple definitions for the same function name in the same scope. When you call an overloaded function or operator, the compiler determines the most appropriate definition to use by comparing the argument types you used to call the function or operator with the parameter types specified in the definitions.

// From: https://www.tutorialspoint.com/cplusplus/cpp_overloading.htm

iv. Explain the difference between "pass by reference" in C and "pass by reference" in C++.

In C, the function argument must defined as a pointer (memory address), like *wp, which can be accessed by either (*wp).x or wp->x. When passing a pointer to a function, the address it contains is copied into the function. Modifying that pointer inside the function will not change the pointer outside the function - however, modifying the object it points to will change the object outside the function.

In C++, it is an explicit reference, like &wp, which can be accessed by wp.x. When passing an argument to a function that takes reference type, the object is truly passed by reference. There are no pointers involved, no copying of objects, nothing. The name inside the function actually refers to exactly the same object that was passed in.

// From: http://stackoverflow.com/questions/13654138/what-exactly-is-the-difference-between-pass-by-reference-in-c-and-in-c

v. Explain what operator type overloading is, and why it could be useful

Overloaded operators are functions with special names the keyword operator followed by the symbol for the operator being defined. Like any other functions, an overloaded operator has a return type and a parameter list. Because you can define the same operater with different type or numbers of arguments. It can choose the most appropriate operater by comparing the argument type or numbers you used.

vi. Finish implementing the needed functions, and make sure your code compiles and runs. Explain the output carefully.

Output and explanation:

-----Pass by value test-----
Original 3 vector:
3-Vector : [0, 0, 0]                 # Print the value of Vec3 before set_vec3, which uses pass-by-value.
Original 3 vector after modification:
3-Vector : [0, 0, 0]                 # Print the value of Vec3 after set_vec3, but the result stays the same because it uses pass-by-value, which does not change the value of outside function.
New 3 vector after modification:
3-Vector : [1, 2, 3]                 # It returns the modified value of vprime.
-----Pass by reference test-----
Original 2 vector:
2Vector : [0, 0]                     # Print the value of Vec2 before set_vec2, which uses pass-by-referess.
Original 2 vector after modification:
2Vector : [1, 2]                     # Print the value of outside value of Vec2, which has been changed to the new value because it uses pass-by-reference.

-----Operator+ Vec3 test-----
Original 3 vector:
3-Vector : [1, 2, 3]
The sum of two vprimes is:
3-Vector : [2, 4, 6]
-----Operator+ Vec2 test-----
Original 2 vector:
2Vector : [1, 2]
The sum of two vprimes is:
2Vector : [2, 4]                     # Added two tests for the newly-written operator+ functions.