COP3330 Exam 1, Exam 2, and Fake Final

Réussis tes devoirs et examens dès maintenant avec Quizwiz!

The ________ operator is used to get the address of a statically allocated variable.

& (aka ampersand) (Note: * is the dereference operator, aka the asterisk/splat/star.)

The ________ operator is used to dereference a pointer.

* ---------------------COMMENTS--------------------------- - the * asterisk/star gives you the dereference of the pointer which is the value of the pointer - to get the address of a statically allocated variable, you use the ampersand & operator)

The ________ operator is used to link a member function to a class.

:: (aka scope resolution)

Consider the following code: === simplelist.h === #include <iostream> using namespace std; const int MAX = 10; template< class T > class SimpleList { public: SimpleList(); bool Insert(T item); // inserts item into list (if room) T GetElement(unsigned int n); // returns element at index n void Print(); // prints the list int GetSize(); // number of stored items (max is 10) private: T array[MAX]; int current; // number of stored items (max is 10) }; #include "simplelist.hpp" === simplelist.hpp === template< class T > SimpleList< T >::SimpleList() { current = 0; } template< class T > bool SimpleList< T >::Insert(T item) { if (current < MAX) { array[current] = item; current++; return true; } else { return false; } } template< class T > T SimpleList< T >::GetElement(unsigned int n) { if (n >= MAX) { n = MAX - 1; } return array[n]; } template< class T > void SimpleList< T >::Print() { if (current == 0) { cout << "Empty List"; return; } int i; for (i = 0; i < current-1; i++) { cout << array[i] << ' '; } cout << array[i]; } template< class T > int SimpleList< T >::GetSize() { return current; } === main.cpp === #include <iostream> #include "simplelist.h" // whole template #included - which means definitions too using namespace std; int main() { SimpleList< int > list1; for (int i = 0; i < 15; i++) { list1.Insert(i * 2); list1.Print(); // <--- THIS LINE OF CODE } } QUESTIONS: (1) What is printed to the terminal by the indicated line of code when i = 0? (2) What is printed to the terminal by the indicated line of code when i = 7? (3) What is printed to the terminal by the indicated line of code when i = 15? (4) What bug is introduced into this code by making the parameter passed into GetElement an int rather than an unsigned int? (Fake Final, Questions #21-24)

ANSWERS: (1) 0 (2) 0 2 4 6 8 10 12 14 (3) 0 2 4 6 8 10 12 14 16 18 (4) Feasibly, a person could pass a negative value into the function and that would result in a negative index being passed into an array which will logically be (not syntactically, try it) out of bounds error. ---------------------COMMENTS--------------------------- (1) So we go to int main() and call both list1.Insert(0); and list1.Print(); - So go to Insert, we see that we do current++; so current is no longer 0 and is at least 1 - then we go to Print with current = 1, then we print out this line of code: cout << array[i] << ' '; which gives us 0 (2) list1.Insert(14); list1.Print(); when i = 7, it will be less than 15 so it will get inserted into the list (3) this is the tricky one; if i = 13 but the max value is set to 10, we have to stop at i = 10 because it will return false by then (4) this is also a tricky one; c++ does actually allow you to pass in negative values but if you pass in negative values, you will very likely get 0 but we can restrict someone from calling something arbitrary like -713 by making it an unsigned int so that they get a compiler error or the unsigned version of their number

Consider the following code: // HEADER === animal.h === #include <iostream> #include <cstring> using namespace std; class Animal { protected: int age; char* name; double weight; public: virtual void MakeSound( )=0; Animal(int _age, double _weight, const char* _name); char* GetName( ); }; class Dog : public Animal { public: void MakeSound( ); Dog(int _age, double _weight, const char* _name); }; class Cat : public Animal { public: void MakeSound( ); Cat(int _age, double _weight, const char* _name); }; // IMPLEMENTATION === animal.cpp === #include "animal.h" using namespace std; void Dog::MakeSound() { cout << "Bark, Bark!" << endl; } void Cat::MakeSound() { cout << "Meow!" << endl; } Animal::Animal(int _age, double _weight, const char* _name) { age = _age; weight = _weight; name = new char[strlen( _name + 1)]; strcpy(name, _name); } char* Animal::GetName() { return name; } Dog::Dog(int _age, double _weight, const char* _name) : Animal( _age, _weight, _name) {} Cat::Cat(int _age, double _weight, const char* _name) : Animal( _age, _weight, _name) {} // DRIVER PROGRAM === app.cpp === #include "animal.h" using namespace std; int main() { Animal** myAnimals = new Animal*[3]; Dog dog1(3, 12.5, "spot"); Dog dog2(1, 22.5, "brrgllgrrgll"); Cat cat(1, 6, "Javier the Incredible"); myAnimals[0] = &dog1; myAnimals[1] = &dog2; myAnimals[2] = &cat; for (int i = 0; i < 3; i++) { myAnimals[i]->MakeSound( ); } } QUESTIONS: (1) When i = 0, what prints to the screen when mtyAnimals[i]->MakeSound() is called? (2) When i = 2, what prints to the screen when mtyAnimals[i]->MakeSound() is called? (3) What is an alternative expression that is equivalent to myAnimals[i]->MakeSound()? (4) What would print when i = 1 when myAnimals[i]->MakeSound() is called if this declaration in animal.h: virtual void MakeSound()=0; was changed to this: void MakeSound(); and this was added to animal.cpp: void Animal::MakeSound() { cout << "Womp, womp!" << endl; } (Midterm 2, Questions #21-24)

ANSWERS: (1) Bark, Bark! (2) Meow! (3) (*myAnimals[i]).MakeSound( ) (4) Womp, womp! ---------------------COMMENTS--------------------------- A common error for (1) and (2) in this question was when students printed the name of the animal instead of printing its corresponding cout statement. (3) was also a highly missed question with a lot of people putting "myAnimals[i].MakeSound()" as their answer. This is an error because at compile time, we will have no idea what MakeSound() is on an animal ptr. Thought process for (3)'s answer --> You have to surround myAnimals[i] with parentheses and put a star asterisk to dereference which takes you from the ptr to the actual animal in the memory/heap and then use the dot operator for access to the functional member on that object, NOT the reference to the object.

Consider the following declaration and definition of a Timer class: // DECLARATION: class Timer { private: int ticks; public: Timer(); void Increment(); void Add(Timer t); }; // DEFINITION: #include <"timer.h"> Timer::Timer() { ticks = 0; } void Timer::Increment() { ticks++; } void Timer::Add(Timer t) { ticks += t.ticks; } // DRIVER: #include <"timer.h"> int main() { Timer t1, t2; t1.Increment(); for (int i = 0; i < 11; i++) { if (i%2 == 0) { t2.Increment(); } t1.Increment(); } t1.Add(t2); } QUESTIONS: (1) The value of t1 at the end of the driver function is ________. (2) The value of t2 at the end of the driver function is ________. (3) If "i%2" is changed "i%3", the value of t1 at the end of the driver function is ________. (4) If "i%2" is changed to "i%3", the value of t2 at the end of the driver function is ________. (Midterm 1, Questions #21-24)

ANSWERS: (1) The value of t1 at the end of the driver function is: 18 ticks. (2) The value of t2 at the end of the driver function is: 6 ticks. (3) If "i%2" is changed "i%3", the value of t1 at the end of the driver function is: 16 (4) If "i%2" is changed "i%3", the value of t2 at the end of the driver function is: 4 ---------------------COMMENTS--------------------------- - In the driver class, the range is from 0 to 10. For each increment, t1.Increment() is called. For each increment where i is a factor of 2, t2.Increment() is also called. Then at the end, t2.ticks is added to t1.ticks for the end result of ticks for t1. - At the end of the for loop, t1.ticks = 12 and t2.ticks = 6. - If "i%2" was changed to "i%3", the end of the for loop would result with t1.ticks = 12 and t2.ticks = 4.

A class with at least one purely virtual function is referred to as:

Abstract

________ represents a "has a" relationship between two classes in object-oriented programming.

Composition

The ________ design methodology is used when creating a C++ program or class.

DDU: ~ Declare (file.h) ~ Define (file.cpp) ~ Use (file-driver.cpp)

The keyword "friend" is used in a function's:

Declaration

(T/F) By default a function call of the form myPtr->myFunction( ) will bind to the most derived class' implementation.

FALSE - "By default" means that you have not done anything special to the definition. In order to make this statement true, you have to mark myFunction( ) as virtual on the base class' declaration.

(T/F) A derived class can access any of its base class' private data and function members.

FALSE - A derived class can access any of its base class' PROTECTED data and function members.

(T/F) A setter should always be marked const.

FALSE - A getter should always be marked const. A setter's sole job in life is to change the internal state of an object which is the opposite of why you would want to use the const keyword.

(T/F) A purely virtual function is implemented by a base class.

FALSE - A purely virtual function specifically can NOT be implemented by a base class. ---------------------COMMENTS--------------------------- NOTE: If the statement said "A purely virtual function is declared by a base class.", the statement would be considered true. Therefore, base class declares the purely virtual function while the derived class implements the purely virtual function.

(T/F) In either a function or class template, the identifier T can be used for more than one type within the same template.

FALSE - Absolutely false; if this was a true statement, we would have a pretty bad day as a compiler because we would not be able to figure out which one is which. However, this does not necessarily mean that you can only have one version type of that template.

(T/F) Typically, base classes are more specific/specialized than derived classes.

FALSE - Base classes are more GENERAL than derived classes, meaning that derived classes are more specific/specialized than base classes.

(T/F) Constant member functions can call other non-constant functions.

FALSE - Constant member functions can only call other CONSTANT functions.

(T/F) Conversion constructors can accept multiple parameters.

FALSE - Conversion constructors accept only ONE parameter.

(T/F) Classes in C++ can only include data members with built-in types. (Built-in types are the same thing as primitive types.)

FALSE - Data members can be user-defined types, such as when we had the data member of an array of instances of type Student, where Student is a user-defined class type. If this statement was true instead of false, composition/aggregation would not exist and your programming language would perform poorly in terms of functionality.

(T/F) Destructors accept only one parameter.

FALSE - Destructors accept NO parameters.

(T/F) A copy constructor is required even if a class does not include DMA.

FALSE - If a class does not include DMA, a copy constructor is not required because there is an automatic/default copy constructor that creates a shallow copy. ---------------------COMMENTS--------------------------- HOWEVER, if a class does include DMA, then you would be required to declare and implement a deep copy assignment operator and a user-defined copy constructor as part of the Rule of Three, with the destructor being the third part.

(T/F) Copy constructors should always take in two parameters.

FALSE - If you theoretically think of it, a copy constructor is a conversion constructor from the type back to itself and if it is like a conversion constructor, a copy constructor should take in only ONE parameter.

(T/F) Objects are templates for classes.

FALSE - Objects are instances of a class while classes are templates for objects.

(T/F) Classes are instances of objects.

FALSE - Objects are instances of classes.

(T/F) The definition of a friend function requires the use of the scope resolution operator.

FALSE - The definition of a MEMBER function requires the use of the scope resolution operator in addition to also using the dot operator.

(T/F) A class template can only contain a single template function.

FALSE - This is literally disproven in the later part of the Fake Final exam where we have to read and understand a class template with multiple template functions.

(T/F) The new keyword can be used to re-allocate memory without explicitly deleting space previously allocated to that location.

FALSE - You MUST explicitly delete the space previously allocated to that location or else you will run into segmentation faults (yucky). ---------------------COMMENTS--------------------------- In addition to this case being a common reason why segmentation fault occurs, the other common cases are below: 1) when a user deletes something that you do not have access to (aka when it is not yet allocated, aka calling the delete keyword before the new keyword) 2) when a user initializes a pointer value that has not been yet allocated (so you must allocate the space first) 3) when a user allocates the space twice

________ represents an "is a" relationship between two classes in object-oriented programming.

Inheritance (Note: Composition/aggregation differs from inheritance in that it represents an "has a" relationship between two classes in object-oriented programming.)

A(n) ________ is used to set constant data members of a class:

Initialization list

A(n) ________ is used to set constant data members of a class:

Initialization list ---------------------COMMENTS--------------------------- Think about the DungeonBoard class: There is a maximum number of treasurers and a maximum number of mobs that are both set by initialization sets because they're both constant members of the DungeonBoard class. The syntax of an initialization list: ClassName::ClassName(parameters) : nameofConstDataMember(its_value), anymoreConstDataMembers(andits_value)... { // construction logic } Declaration of the constant data members: const int maxTreasures; const int maxMobs; Definition of the constructor with the initialization list: DungeonBoard::DungeonBoard(int _size=10):maxTreasures(_size/2),maxMobs(_size) { // construction logic } We cannot initialize its value in the declaration so this is why we have to take this funky route in the implementation.

Given the provided code in flashcard no. 72, improve the SimpleList class in the previous section by providing: PART A: What changes are needed to make the array data member a dynamically allocated array of an appropriate type? PART B: The DEFINITION for a cop constructor after making the changes from Part A. PART C: The DEFINITION for a destructor after making the changes from Part A. PART D: Given that you have implemented the changes from Part A correctly, what changes would have to be made to the Insert function to support dynamically GROWING the internal storage represented by the array data member? (Fake Final, Questions #29-32)

PART A: - The array data member has to be changed to a pointer of type T. - The constructor would have to use the new keyword to create heap space for the array data member. - The class would have to contain a default max size and some counter for increasing that size. - The class would have to have a growth mechanism that checks to see if the max value is exceeded and if it is resize array to be of appropriate size. - A destructor that deallocates the internal storage of an array. - OPTIONAL: You would really need a double pointer of type T for the first bullet point because you would ideally want you destructor to iteratively destroy each item in the event that those items are dynamically allocated. For the purposes of this course/exercise, this is NOT required for full credit. PART B: template< class T > SimpleList< T >::SimpleList(const SimpleList< T >& s) { delete [ ] array; // remember this is after the changes so I already know I created a pointer of type t called and I have to delete my old one array = new T[s.GetSize()]; for (int i = 0; i < s.GetSize(); i++) { array[i] = s.GetElement(i); } current = s.GetSize(); } PART C: template< class T > SimpleList< T >::~SimpleList() { for (int i = 0; i < current; i++) { delete array[i]; } delete [ ] array; } PART D: - The insert function would need to check the value of current vs the value of the MAX flag. - If current == MAX, the algorithm would then perform the standard resizing steps: ~ Create a new pointer of size MAX + pageSize ~ DEEP copy the values of array into that new array ~ Delete the existing array ~ Point array to the newly created list - Set MAX = current (or MAX) + pageSize

It is confirmed the final contains bitwise operators. NOTE: Bit shift operators will NOT be included on the final exam. PART A: What are the roles and names of the following bitwise operators below? (1a) & (2a) | (3a) ^ (4a) ~ PART B: What is the arity of ALL bitwise operators? (Part B probably won't matter.) PART C: short x = 6891; short y = 11318; x: 00011010 11101011 y: 00101100 00110110 (1c) x & y = ? (2c) x | y = ? (3c) x ^ y = ?

PART A: (1a) & is the bitwise AND that sets the result to 1 if both bits are 1, 0 otherwise (2a) | is the bitwise OR that sets the result to 1 if AT LEAST one of the bits is 1, 0 otherwise (3a) ^ is the bitwise XOR that sets the result to 1 if EXACTLY one of the bits is 1, 0 otherwise (4a) ~ is the complement that inverts ALL bits. PART B: Arity = binary (because you are comparing the two bits to one other) PART C: (1c) x & y = 00001000 00100010 (2c) x | y = 00111110 11111111 (3c) x ^ y = 00110110 11011101

You might have noticed that the code in flashcard no. 46 was missing the components of the rule of three; good eye! Please provide the following below: PART A: The DECLARATION for a deep copy assignment overload for the Animal class. PART B: The DEFINITION for a deep copy assignment overload for the Animal class. (Midterm 2, Questions #27-28)

PART A: Animal& operator=(const Animal& a); PART B: Animal& Animal::operator=(const Animal& a) { if (*this != a) { weight = a.weight; age = a.age; delete [ ] name; name = new char[strlen(a.name) + 1]; strcpy(name, a.name); } return *this; } ---------------------COMMENTS--------------------------- PART A: The ampersand & is really important. If you do not have &, it will trigger a copy and go into the copy constructor which we do not want. However, it is optional to put const in the declaration. PART B: - In this part, you absolutely must do two things: 1) (shallow) copy all the statically allocated data values, like age and weight and 2) (deep) copy all the dynamically allocated data values, like name. - It would be extremely bad to do this line of code: name = a.name; because then it would be a shallow copy and since name is a dynamically allocated array, you would want a deep copy overload instead. A shallow copy would put the pointer in the other class' data member and once a goes out of scope, you will no longer have access to it and your life will be a mess. If you want your life to become easier, then become very familiar with this formatting instead of the for loop concept: delete [ ] name; name = new char[strlen(a.name) + 1]; strcpy(name, a.name); It is optional to use this-> because you are already scoped to the object in the function. Our last line of code looks like this: return *this; It has to be a dereference pointer because we know that it is returned by reference with the Animal& in its declaration, thereby so it is not the pointer that we want to return but the actual value itself.

(Unsure about Part B) You might have noticed that the code in flashcard no. 46 was missing the components of the rule of three; good eye! Please provide the following below: PART A: The DECLARATION for a copy constructor for the Animal class. PART B: The DEFINITION for a copy constructor for the Animal class. (Midterm 2, Questions #29-30)

PART A: Animal(const Animal& a); PART B: Animal::Animal(const Animal& a) { weight = a.weight; age = a.age; name = new char[strlen(a.name) + 1]; strcpy(name, a.name); } ---------------------COMMENTS--------------------------- This answer will be very similar to the answer in flashcard no. 49. As stated in the Zoom lecture, the differences between the copy constructor and the deep copy assignment overload are stated in the following below: ~ In the copy constructor's name, the operator= that was in the assignment overload will be replaced with Animal; however, the copy constructor will still retain the same parameters as the assignment overload. ~ There will no return value in the copy constructor because it is a constructor. ~ The implementation's code for the copy constructor is going to be the exact same as the assignment overload EXCEPT you will omit the part with deleting the dynamically allocated data members/values because you know that you are constructing something for the first time and the keyword new has not been used yet. And we know that if you try to delete something that has not yet been allocated, you will get a segmentation fault. Be careful with not forgetting to take out the delete for DMA because this is a commonly missed part of the question!

Given the same declaration, definition, and driver from flashcard no. 21, please provide the following: PART A: The DECLARATION of an operator overload for the "++" operator that adds 1 tick to the Timer implemented as a MEMBER FUNCTION. PART B: The DEFINITION of an operator overload for the "++" operator that adds 1 ticks to the Timer implemented as a MEMBER FUNCTION. (Midterm 1, Questions #29-30)

PART A: Timer operator++(); PART B: Timer Timer::operator++() { Timer t; t.ticks = t + 1; return t; }

Given the same declaration, definition, and driver from flashcard no. 21, please provide the following: PART A: The DECLARATION of a MEMBER FUNCTION that allows the timer to increment an arbitrary number of ticks. PART B: The DEFINITION of a MEMBER FUNCTION that allows the timer to increment an arbitrary number of ticks. (Midterm 1, Questions #25-26)

PART A: Void Increment(int _ticks); PART B: There are two possible ways to answer this question. ~~ Option 1 ~~ Void Timer::Increment(int _ticks) { ticks += _ticks; } ~~ Option 2 ~~ Void Timer::Increment(int _ticks) { for (int i = 0; i < _ticks; i++) { Increment(); } }

Given the same declaration, definition, and driver from flashcard no. 21, please provide the following: PART A: The DECLARATION of a FRIEND FUNCTION that subtracts the ticks of one Timer from another Timer. PART B: The DEFINITION of a FRIEND FUNCTION that subtracts the ticks of one Timer from another Timer. (Midterm 1, Questions #27-28)

PART A: friend Timer subtract(const Timer& t1, const Timer& t2); PART B: Timer Subtract(const Timer& t1, const Timer& t2) { Timer t; t.ticks = t1.ticks - t2.ticks; return t; }

Given the same declaration, definition, and driver from flashcard no. 21, please provide the following: PART A: The DECLARATION of an operator overload for the "==" operator that compares the ticks of two Timer instances and returns if they are equal implemented as a FRIEND FUNCTION. PART B: The DEFINITION of an operator overload for the "==" operator that compares the ticks of two Timer instances and returns if they are equal implemented as a FRIEND FUNCTION. (Midterm 1, Questions #31-32)

PART A: friend bool operator==(const Timer& t1, const Timer& t2); PART B: friend bool operator==(const Timer& t1, const Timer& t2) { if (t1.ticks == t2.ticks) { return true; } else { return false; } }

Given the provided code in flashcard no. 72, improve the SimpleList class in the previous section by providing: PART A: The DECLARATION of a function called "PrintHalf" that takes in a bool and prints the first half of the list if the parameter is false and the second half of the list if the parameter is true. If the list has an odd number of items, the first half should print an additional item when compared to the second. PART B: The definition for the function declared in Part A. (Fake Final, Questions #27-28)

PART A: void PrintHalf(bool secondHalf); PART B: template< class T > void SimpleList< T >::PrintHalf(bool secondHalf) { int halfSize = current / 2; // revenge of the modulus if (current%2 == 1) { halfSize++; } int start = 0, end = 0; // true if (secondHalf) { start = halfSize; end = current - 1; } // false else { start = 0; end = halfSize - 1; } if (current == 0) { cout << "Empty List"; return; } int i; for (i = start; i < end; i++) { cout << array[i] << ' '; } cout << array[i]; } ---------------------COMMENTS--------------------------- PART B: - If I am trying to print half of a list, I want to figure out the size and I implement that with int halfSize = current / 2;

Here is another example dealing with bitwise operators: x = 0101110 00011010 y = 1101001 01010101 PART A - Bitwise "and" (&): x & y = 0101110 00011010 & 1101001 01010101 = ??? PART B - Bitwise "or" ( | ): x | y = 0101110 00011010 | 1101001 01010101 = ??? PART C - Exclusive Bitwise "or" (i..e, "xor") (^): x ^ y = 0101110 00011010 ^ 1101001 01010101 = ??? PART D - Bitwise Complement (~): ~x ~ 0101110 00011010 = ??? PART E - Bitwise Complement (~): ~y ~ 1101001 01010101 = ???

PART A: x & y = 0101110 00011010 & 1101001 01010101 = 0101000 00010000 PART B: x | y = 0101110 00011010 | 1101001 01010101 = 1101111 01011111 PART C: x ^ y = 0101110 00011010 ^ 1101001 01010101 = 1000111 01001111 PART D: ~x ~ 0101110 00011010 = 1010001 11100101 PART E: ~y ~ 1101001 01010101 = 0010110 10101010

You might have noticed that the code in flashcard no. 46 was missing the components of the rule of three; good eye! Please provide the following below: PART A: The DECLARATION for a destructor for the Animal class. PART B: The DEFINITION for a destructor for the Animal class. (Midterm 2, Questions #25-26)

PART A: ~Animal(); PART B: Animal::~Animal() { delete [ ] name; } ---------------------COMMENTS--------------------------- PART B: Some people put the following below as their answer: Animal::~Animal() { for (int i = 0...) { delete [ ] name; } } You do NOT need to do this because it is not a list of pointers. It is a pointer that is a list of characters so you don't need to delete the actual characters; those are static --> When you leave scope, those will automatically be deleted.

Given the provided code in flashcard no. 72, improve the SimpleList class in the previous section by providing: PART A: The DECLARATION of a function called "Remove" that takes in an unsigned int parameter called "index" and returns the value of the internal array at that index. PART B: The DEFINITION of a function called "Remove" that takes in an unsigned int parameter called "index", removed the value of the internal array at that index, shifts the rest of the array one position to the left, and returns the value that was removed. (Fake Final, Questions #25-26)

PART A: T Remove(unsigned int index); //its return type is T PART B: template< class T > T SimpleList< T >::Remove(unsigned int index) { T value = array[index]; for (int i = index; i < current; i++) { array[i] = array[i+1]; } current--; return value; } ---------------------COMMENTS--------------------------- PART B: We want to remove the index when i = 2. Initial: 0 1 2 3 4 5 After (i+1): 0 1 3 4 5 It is important to decrement because if you do not, you will go too far to the right.

(**Please double check this question because an TA helped me fix some errors on here!) You might have noticed that the code in flashcard no. 46 was missing the components of the rule of three; good eye! Please provide the following below: PART A: Create a dynamically allocated c-style string of size 15. PART B: Given a dynamically allocated array of c-style strings of size 10 (that have all been initialized) called myStrings, provide the algorithm to resize this array to an array of size 15.

PART A: char* myString = new char[16]; PART B: // Step 1: First, create an entirely new array with the new size of 15. char** tempStrings = new char*[15]; // Step 2: Second, copy the data from your old array to the new array. for (int i = 0; i < 10; i++) { tempStrings[i] = myStrings[i]; } // Step 3: Third, destroy the previous array. delete [ ] myStrings; // Step 4: Lastly, fix the pointer. myStrings = tempStrings; ---------------------COMMENTS--------------------------- PART B: - Most people got this correct, and what they ultimately did was use shallow copies to copy this string into the old version of the list into the same position of the new list --> You can not just use = assignment; you have to use strcpy or copy it over character by character. - Note that this is an array of an array (particularly of c-style strings) making this a 2-D array, so we must use double pointers. - You loop through 10 because you only have 10 in the original array.

The ________ stores statically allocated memory in a C++ program.

Stack ---------------------COMMENTS--------------------------- Stack - Statically Heap - Dynamically (Think about how both Stack and Statically start with an 'S')

(T/F) A class can have an arbitrary number of constructors.

TRUE

(T/F) A driver program can create an arbitrary number of objects from a class.

TRUE

(T/F) Copy constructors must take their parameters in by reference.

TRUE ---------------------COMMENTS--------------------------- Example of a copy constructor from Midterm 2: // declaration Animal(const Animal& a); // definition Animal::Animal(const Animal& a) { weight = a.weight; age = a.age; name = new char[strlen(a.name) + 1]; strcpy(name, a.name); }

(T/F) Statically allocated objects can be added to a heterogenous array.

TRUE ---------------------COMMENTS--------------------------- The T/F question is basically asking "Can I physically add a statically allocated object to a heterogeneous array?" The answer is absolutely yes. BUT this does not mean it is a good idea because if you somehow cross the scope boundary then your statically allocated object will get deallocated and your pointer will point to nowhere land.

(T/F) A constructor cannot be called on a class with any purely virtual function.

TRUE - A class with any purely virtual function is an abstract class and since an abstract class cannot have any of its constructors called, this statement is true.

(T/F) A class can have only one implementation of an override for a given operator.

TRUE - If you had multiple implementations of the ++ operator, the compiler would not understand which one to link to the symbol.

(T/F) A driver program cannot access private data or function members.

TRUE - The IMPLEMENTATION CLASS can access private data or function members. The driver programs, however, can access public data or function members.

(T/F) The -c flag is used to create object code from a source cpp file with g++.

TRUE - The c flag is used to create .o file, which is an object file.

(T/F) In C++, classes can have an arbitrary number of parent (i.e., base) classes.

TRUE - This C++ feature is referred to as multiple inheritance.

(T/F) For an array to be resizable in C++, it must be stored in heap space.

TRUE - This goes back to the definition of statically vs dynamically allocated memory. In order for an array to be resizable, it has a dynamically allocated array. Subsequently, to be a dynamically allocated array, it must be a pointer from the stack space to the heap space.

(T/F) When working with a dynamically allocated list of dynamically allocated objects in C++, you must clear each individual object instance AND the list that originally contained those references.

TRUE - This is absolutely true. This doesn't say anything about where it has to happen; it just says that it does have to happen.

(T/F) A pointer of a base class type can reference a derived class type.

TRUE - This is the reason why we can have heterogeneous lists in C++.

(T/F) Multiple class declarations can be put into a single header file.

TRUE - Typically separating multiple class declarations into different files rather than a single file is preferred (in school and jobs, basically anywhere) because it will be easier to read and compile in addition to being easier to ship one class instead of the entire library of classes when working with groups that have members consisting of different roles for the project. ---------------------COMMENTS--------------------------- It is important to note that if all those classes are in the header file, it would increase compilation time because it runs all the classes the header file which would be inconvenient, especially when a user just wants to modify one specific class.

If you are given a dynamically allocated array of a given size, you can resize the array as such: SomeClass** myClasses = new SomeClass*[5]; SomeClass** temp = new SomeClass*[10]; for (int i = 0; i < 10; i++) { temp[i] = myClasses[i]; } // LOOK AT THIS FOR MY NEXT MESSAGE // this is only required if the values are initialized for (int i = 0; i < 10; i++) { delete myClasses[i]; } delete [ ] myClasses; myClasses = temp;

This was written on Discord by Dr. Mills as an example for resizing in relation to double pointers. ---------------------COMMENTS--------------------------- - When values are already initialized, why do we have to delete each element of the array list before deleting the array list itself? Because when you delete the top level pointer defining the whole array, you have no guaranteed way to reference the elements anymore, so you wouldn't be able to delete them and it would be a memory leak.

The Rule of ________ is used to ensure that memory management for a user-defined type is consistent with that for built-in types and helps avoid segmentation faults when consuming that user-defined type.

Three

The -- operator is:

Unary

Which of the following deallocates heap space associated with a dynamically allocated object called myObject? a. delete myObject; b. delete *myObject; c. delete { } myObject; d. delete [ ] myObject;

a. delete myObject; ---------------------COMMENTS--------------------------- Remember, this is an object, NOT an array of objects so there should be no brackets associated with it.

________ represents a "has a" relationship between two classes in object-oriented programming language.

aggregation

Which of the following declares appropriate storage for a resizeable c-style string? a. string myString; b. char* myString; c. string* myString; d. char** myString;

b) char* myString; ---------------------COMMENTS--------------------------- INCORRECT & WHY: a --> C-style is in bold so that would be a object of type string, not c-string. c --> That would be a list of objects of type string. d --> That would be a list of c-style strings.

The = operator is: a. Unary b. Binary c. Ternary d. Quaternary

b. Binary (There is a left-hand side and a right-hand side of the operator. Ex: x + y = z)

Which of the following is NOT an automatic in C++? a. Default Constructor b. Destructor c. Deep Copy Assignment d. Shallow Copy Assignment

c. Deep Copy Assignment (The user has to manually define the deep copy assignment operation function.)

Which of the following declares appropriate storage for a list of six resizable c-style strings? a. string myString; b. char* myString; c. string* myString; d. char** myString;

d. char** myString; ---------------------COMMENTS--------------------------- - what the question is saying that it needs a pointer of pointers - outside pointer is going to tell me that im gonna get a list to do something with char - inner pointer is not only gonna be a list of char's but it's going to be a list of list of char's (what allows us to have six resizable c-strings)

Which of the following deallocates heap space associated with a dynamically allocated array named myArray? a. delete myArray; b. delete *myArray; c. delete { } myArray; d. delete [ ] myArray;

d. delete [ ] myArray; (Provided by a TA) Usually, when you dynamically allocate and delete an array of something it looks like: char *str = new char[10]; delete [ ] str; ---------------------COMMENTS--------------------------- INCORRECT & WHY: a --> That would only delete the first element in that list. b --> This is the incorrect answer as the correct formatting is delete [ ] str; but delete *myArray; could be used for a 2-D array of dynamically allocated ints. int **myInts = new int*[10]l for (int i = 0; i <10; i++) { myInts[i] = new int; } Technically if you called delete *myInts, it would deallocate the first dynamically allocated int in the array. A better example for this is if it were with a class: Square **mySquares = new Square*[10]; for (int i = 0l i < 10; i++) { mySquares[i] = new Square(5); } But it wouldn't really make sense to delete just the first item with that syntax because it's a little weird so we would expect instead delete mySquares[0] instead (it means the same thing). TLDR: You probably just need to focus on delete and delete [ ] and knowing when to switch. delete myArray; //deletes the first element in the array delete [ ] myArray; // deletes the whole list in the array c --> { }, aka curly brackets, is used to begin the body of a function, class, if/else statement, or loop; thus, { } cannot be used in a delete statement.

Classes encapsulate two types of member: function members that define business logic and ________ members that define the state of a class.

data

The keyword ________ restricts a conversion constructor from being called implicitly.

explicit

________ is a keyword used to ensure that conversion constructors are NOT used implicitly.

explicit

A(n) ________ function has access to both public and private members of a class but is NOT a member function.

friend

Classes encapsulates two types of members: data members that define state and ________ members that define the behavior of a class.

function ---------------------COMMENTS--------------------------- Function - Behavior Data - State (Think of function as in what does it do and data as in what is the stats of the data and stats is close to spelling in state)

When creating an operator override, the keyword ________ is used to name the implementation method:

operator

The keyword ________ restricts access to data and function members of a class and its derived classes.

protected

++ is a(n) ________ operator.

unary

The name of a destructor must begin with the special character:

~ (aka Tilda)


Ensembles d'études connexes

Prep-U Ch. 44 - Digestion and GI Function

View Set

Family Medicine 05: 30-year-old female with palpitations

View Set

Introduction to Networking: Wireless

View Set

List of Common Cations and Anions

View Set

Unit 4 Questions Ch 17-20 combined

View Set