CS106L Midquarter Review
Midquarter review of Stanford CS106L.
stream
stream: an abstraction for input/output. Streams convert between data and the string representation of data.
Output Streams
- Have type
std::ostream
- Can only send data using the
<<
operator- Converts any type into string and sends it to the stream
std::cout
is the output stream that goes to the console
1 | std::cout << 5 << std::endl; |
Output File Streams
- Have type
std::ofstream
- Only receive data using the
<<
operator- Converts data of any type into a string and sends it to the file stream
- Must initialize your own
ofstream
object linked to your file
1 | std::ofstream out(“out.txt”, std::ofstream::out); |
Input Streams
- Have type
std::istream
- Can only receive data using the
>>
operator- Receives a string from the stream and converts it to data
std::cin
is the output stream that gets input from the console
1 | int x; |
Nitty Gritty Details: std::cin
- First call to std::cin >> creates a command line prompt that allows the user to type until they hit enter
- Each >> ONLY reads until the next whitespace
- Whitespace = tab, space, newline
- Everything after the first whitespace gets saved and used the next time std::cin >> is called
- The place its saved is called a buffer!
- If there is nothing waiting in the buffer, std::cin >> creates a new command line prompt
- Whitespace is eaten: it won’t show up in output
Stringstreams
- Input stream: std::istringstream
- Give any data type to the istringstream, it’ll store it as a string!
- Output stream: std::ostringstream
- Make an ostringstream out of a string, read from it word/type by word/type!
- The same as the other i/ostreams you’ve seen
1 | //ostringstreams |
References
References to variables
1 | vector<int> original{1, 2}; |
The classic reference-copy bug:
1 | void shift(vector<std::pair<int, int>>& nums) { |
The classic reference-rvalue error
1 | void shift(vector<std::pair<int, int>>& nums) { |
- l-values
- l-values can appear on the left or right of an =
x
is an l-value- l-values have names
- l-values are not temporary
- r-values
- r-values can ONLY appear on the right of an =
3
is an r-value- r-values don’t have names
- r-values are temporary
1 | //The classic reference-rvalue error, fixed |
const indicates a variable can’t be modified
1 | std::vector<int> vec{1, 2, 3}; |
const & subtleties
1 | std::vector<int> vec{1, 2, 3}; |
Containers and Iterators
Simple Sequence Containers
1 | graph TB |
1 | graph TB |
What you want to do | std::vector | std::deque | std::list |
---|---|---|---|
Insert/remove in the front | Slow | Fast | Fast |
Insert/remove in the back | Super Fast | Very Fast | Fast |
Indexed Access | Super Fast | Fast | Impossible |
Insert/remove in the middle | Slow | Fast | Very Fast |
Memory usage | Low | High | High |
Combining (splicing/joining) | Slow | Very Slow | Fast |
Stability (iterators/concurrency) | Bad | Very Bad | Good |
Container Adaptors
What is a container adaptor?
std::stack and std::queue
Container adaptors are wrappers in C++
- Container adaptors provide a different interface for sequence containers.
- You can choose what the underlying container is
- For instance, let’s choose a deque as our underlying container, and let’s implement a queue
1 | std::queue<int> stack_deque; // Container = std::deque |
Associative Containers
1 | //set |
1 | //map |
STL Iterators
- Iterators are objects that point to elements inside containers.
- Each STL container has its own iterator, but all of these iterators exhibit a similar behavior!
- Generally, STL iterators support the following operations:
1 | std::set<type> s = {0, 1, 2, 3, 4}; |
Why ++iter and not iter++?
Answer: ++iter returns the value after being incremented! iter++ returns the previous value and then increments it. (wastes just a bit of time)
Looping over collections
1 | //初始 |
Pointers
- When variables are created, they’re given an address in memory.
- Pointers are objects that store an address and type of a variable.
classes
A programmerdefined custom type. An abstraction of an object or data type.
Sections
- Public section:
- Users of the Student object can directly access anything here!
- Defines interface for interacting with the private member variables
- Private section:
- Usually contains all member variables
- Users can’t access or modify anything in the private section
Constructors
- Define how the member variables of an object is initialized
- What gets called when you first create a Student object
- Overloadable
Destructors
- Arrays are memory WE allocate, so we need to give instructions for when to deallocate that memory!
- When we are done using our array, we need to
delete []
it!
Template classes
1 | //mypair.cpp |
Member Types
- Sometimes, we need a name for a type that is dependent on our template types
- iterator is a member type of vector
1 | //vector.h |
Aside: Type Aliases
- You can use using type_name = type in application code as well!
- When using it in a class interface, it defines a nested type, like vector::iterator
- When using it in application code, like main.cpp, it just creates another name for type within that scope (until the next unmatched })
Summary
- Used to make sure your clients have a standardized way to access important types
- Lives in your namespace:
vector<T>::iterator
- After class specifier, you can use the alias directly (e.g. inside function arguments, inside function body)
- Before class specifier, use typename.
Recap
Template classes
- Add
template<typename T1, typename T2 ...>
before class definition in .h - Add
template<typename T1, typename T2 ...>
before all function signature in .cpp - When returning nested types (like iterator types), put
template<typename T1, typename T2 ...>::member_type
as return type, not justmember_type
- Templates don’t emit code until instantiated, so
#include
the .cpp file in the .h file, not the other way around
Const and Const-correctness
- Use const parameters and variables wherever you can in application code
- Every member function of a class that doesn’t change its member variables should be marked
const
- auto will drop all const and &, so be sure to specify
- Make iterators and const_iterators for all your classes!
- const iterator = cannot increment the iterator, can dereference and change underlying value
- const_iterator = can increment the iterator, cannot dereference and change underlying value
- const const_iterator = cannot increment iterator, cannot dereference and change underlying value