1/16
Looks like no tags are added yet.
Name | Mastery | Learn | Test | Matching | Spaced | Call with Kai |
|---|
No analytics yet
Send a link to your students to track their progress
why do we do operator overloading?
we can’t normally do operations on custom objects from classes with, for example, obj3 = obj1 + obj2 , so we use operator overloading to allow us to do this
what is the code format for operator overloading
ClassName operator[operator symbol] (ClassName rhs_var)
what are two rules with operator overloading? and what is something annoying about scalar operations?
we can only use existing operation symbols and can’t make new ones
the inherent rules of the operators cannot be changed (e.g. associativity, or PEMDAS, or num arguments for an operator (addition rquires 2))
scalar operations must be done such that the EXISTING obj is on the left side, while something else like a scalar is on the right. e.g. obj1 + 5 is correct.
which operators can NOT be overloaded?
?:
.
.*
::
sizeof
typeidwhat is the solution to the left hand rule? and what problem does that create and how do we deal with them?
we define overloaded operator as a global function. this is an issue too as global overloaded operators can’t access class methods.
solution 1: add public getter and setter functions to class
solution 2: in the class, declare the operator function too, but as a friend. ex:
ClassName operator[operator symbol] (ClassName rhs_var) // global
ClassName {
...
friend ClassName operator[operator symbol] (ClassName rhs_var)
...
}note: friendship is one way. if class A is B’s friend, B is not necessarily A’s friend unless explicitly declared so
how many argument counts are in binary and unary overloaded operators?
Binary:
member is 1: a+b is a.operator+(b)
global is 2: a+b is a.operator+(a, b)
Unary:
member is 0: +a is a.operator+();
global is 1: +a is operator(a)
how does the compiler know the difference between prefix and postfix (e.g. ++a vs a++ ) if both are increment operators?
for postfix, it requires you to put a dummy int variable inside:
a.operator+(int) or operator+(a, int)
what does STL give us and when are data types that are stored decided
it gives us containers data structures, iterators, and algorithms to use them. data types are decided at compile time, making type safety good.
what are the three kinds of containers?
sequence container: complete control of where the data goes (ex: vector)
associative container: dropping in items go automatically to where they belong based on a sorting rule (ex: map, key-value)
container adapter: restrict sequence containers for specific behavior (ex: stacks)
what are iterators? how do you get read-only iterators? example of declaring an iterator for a vector?
they act like pointers (pointer is actually an example of an iterator for an array), and can be controlled back and forth. there are two kinds, forward and backwards iterators. forward has begin, end, while reverse has rbegin, rend.
you get const_iterator which is a read-only iterator.
btw, iterators must be declared with respect to the datatype of their container (e.g. map)
example vector declaration: std::vector <type>::iterator iterVar;
what are vectors?
notation?
what is the time complexity of access to entries
what happens when vector memory is exhausted?
what are the 11 functions you can use with vectors?
vectors are arrays of adjustable size (keep track of size and capacity)
std::vector <type> v;
constant
the vector allocates a larger contiguous area of memory, then copies itself there and deallocates old memory. vector usually doubles in size.
methods of vectors:
v[elementIndex] gives value at that index, WITHOUT bounds checking
v.at(elementIndex) gives value at that index, WITH bounds checking
v.front()
v.back()
v.push_back(value) adds an element to the end
v.size()
v.capacity() tells how much vector can hold before it reallocates more memory
v.insert(iterator, value) insert BEFORE location of iterator
v.erase(iterator) delete item AT the iterator position
v.erase(iter1, iter2) erase elements between iter1 and iter2, not including iter2
v.clear() erase entire vector
how do you declare a map
map<key type, value type> myMap;
why are maps useful? why is the key useful? what is a rule regarding the key?
maps are good for symbol tables, implementing lexical analyzer, parser, interpreter, etc. key is used for sorting and uniquely identifying. two elements cannot have the same key.
how do we access elements in maps, & what happens if element doesn’t exist? how does the iterator sort through the map (order) ?
we access elements with myMap[key] , and if it doesn’t exist, the element is immediately created. iterator sorts by the key-order.
how do we look for elements in a map?
we use the .find(key) which returns an iterator pointing to an element should it exist. if it doesn’t exist, it returns myMap.end(), so to iterate and search for an element in a map, we do:
if (myMap.find(key) == myMap.end()) {
// key not found
}how do we delete items in a map?
using erase , as setting to zero or null doesn’t work
yk how in maps, stuff is stored like <key, value> ? well, how do we use an iterator to cop ONE of these items?
let’s say iterator is called iter . we’ll do:
cout« it → first « endl; , and that it→second or first chooses and dereferences the key or value at the pair iterator points to.