TRUE/FALSE: You can resubmit your code through Gradescope infinitely before the deadline
TRUE!
What is a Class?
A user-defined data type. You can think of it as a blueprint to whatever object you're trying to build
What is the Rule of Three?
If I have a DESTRUCTOR, I must also have:
- COPY CONSTRUCTOR
- ASSIGNMENT OPERATOR
Why do we need to check the validity of input?
We cannot trust that all input is safe/compatible with the program.
Leaving input unchecked can cause the code to become vulnerable to threats such as SQL injections
Define a memory heap!
Dynamic memory allocation. Memory is allocated/deallocated during runtime rather than during compile time.
You can think of it as an extra place for memory that's intended to only be used while the program is running.
Analogy: In a public bath, they let you use a storage box to put your stuff while you use the facilities. The only condition is that you have to take your stuff out once you're done so the storage boxes are cleaned and ready to be used again next time.
TRUE/FALSE: Programming Assignments + Labs are submitted via ZyBooks
FALSE! Programming Assignments + Labs are submitted via Gradescope
What is the difference between a Class and a Struct?
Class: data members are PRIVATE on default
Struct: data members are PUBLIC on default
Why do we need to make our own copy constructors and assignment operators?
Because when we create a destructor with no copy constructors and assignment operators, C++ will generate its own version which will only make shallow copies among other problematic behaviors
When extracting data from a file stream, how do we validate its content?
ex.
inFS >> info; // how do we check if info is valid?
We use .good() to check if any errors occurred while extracting data into info
ex.
inFS >> info;
if (!(inFS.good())) { throw ... }
What are the two properties of a memory heap?
1) It is DYNAMICALLY SIZED, meaning its resizable.
2) It is PERSISTENT, meaning that whatever is allocated on the heap will remain until it is explicitly deallocated (with delete) or the program itself is terminated.
Basically, whenever we call something with new, we are allocating it on to the heap. Thus, to deallocate it, we need to later call delete.
TRUE/FALSE: Students are not allowed to collaborate on Programming Assignments
FALSE! You are allowed to ask each other questions and help guide each other (after all, everyone codes differently). This does not mean you can copy other's work!
What is a shallow copy and why is it problematic? In turn, what is a deep copy?
Given *object1 that points (links) to a object2...
Shallow copy: makes copy of *object1 and its link but not the data of object2 that it points to. WHY BAD? When destructor tries to delete the data of what *object1 and object2 points to/represents, both will attempt to delete the same data causing the program to crash
Deep copy: makes new, separate copy of object2 so that *object1 points to a separate object2 than the original object2
Define .good(), .fail(), and .eof()!
*Include what states they have by default
.good() : "True" by default. Returns "False" when an error occurs during operation.
.fail() : "False" by default. Returns "True" when an error occurs during operation.
.eof() : "False" by default. Returns "True" only when it has processed data and reached a point where there is no more data. Thus, it cannot correctly check if a file is empty as there is no data to process in the first place.
Draw a visualization of:
1) A program with some data, and a pointer that points to said data
2) A continuation of 1), except now we call delete
i cant put images here without paying sooo check the whiteboard
FALSE! I just came up with that idea
I want to write a bool function that finds an instance of a user-inputted character in a given string. What's the ideal way to code this?
bool hasChar(const std::string &str, const std::string &targetChar) {
return str.find(targetChar,0) == 0; // if 0 is returned, targetChar is found
}
Write the default constructor and rule of three as per Pat's directions in the given the class:
class Bar {
int *ptr;
public:
};
class Bar {
int *ptr;
public:
Bar() : ptr(new int(0)) {}
~Bar() { delete ptr; }
Bar(const Bar&) = delete;
Bar& operator = (const Bar&) = delete;
};
// note this is the lazy way to do it, but it's still better than letting C++ handle things for us. Pat will also accept this method (most of the time)
BONUS: What are the different ways we can de-reference a pointer (as explained by Pat)?
Given:
int* p = ...
p[i] = *(p + i) = i[p]
Given:
Foo f;
Foo* p = &(f);
cout << p->data << endl; // where data is a member of Foo object
What should we do after deleting a pointer?
Reset it to point to nullptr.
WHY? Pointers point to addresses. When we try to "delete pointers", we're actually deleting the data that's inside the address they point to. Even after deleting the data, the pointers still point to the same address. To prevent "dangling pointers", it's good practice to reset the pointers to point to nullptr, that way it's not pointing to anything.