STL overview part 2

The Standard Template
Library – part 2
auto_ptr<>

Regular pointers may cause memory leaks
void f()
{
SomeClass *ptr = new SomeClass;
…
// exception or improperly implemented early return from f()
…
delete ptr; // memory leak if this statement is not reached
}

The memory leak may be avoided


We may use exception mechanism to catch exceptions
We shoud delete all allocated memory in case of early return
auto_ptr<>

auto_ptr is an object (template) that



Acts as an inteligent pointer
Owns data assigned to it
Manages asigned data to avoid memory leaks

(defined in <memory> header)
void f()
{
std::auto_ptr<SomeClass> ptr(SomeClass);
…
// exception or early return from f() – ok!
…
// no need to delete ptr; ~auto_ptr() does it for us
}
auto_ptr<>

auto_ptr owns data assigned to it

Assignment from regular pointer not allowed
// std::auto_ptr<SomeClass> ptr = new SomeClass; ERROR, but there is a reset()

There may be only one one auto_ptr that owns specific object/variable



copy constructor and assignment operator move data from source auto_ptr, so they
modify their arguments – unusual behaviour
auto_ptr should not be an element of a container (why?)
auto_ptr acts as an inteligent pointer




Overloads *(ptr) and ptr->
It is a pointer to single object, not to an array, container – ok.
Does not overload pointer arithmetic operators (++, [], etc)
Extra methods :



T* get() – returns address of the owned data (or NULL), not changing ownership
T* release() – returns address of the owned data (or NULL), releasing ownership
void reset(T * ptr=0) – assignment from regular pointer, creating ownership
auto_ptr<>

copy constructor
std::auto_ptr<SomeClass> ptr1(SomeClass);
std::auto_ptr<SomeClass> ptr2(ptr1);
// now ptr1 is empty

assignment operator
std::auto_ptr<SomeClass> ptr1(SomeClass);
std::auto_ptr<SomeClass> ptr2(SomeClass);
ptr2=ptr1;
// *ptr2 (old one) gets destructed first,
// now ptr1 is empty
auto_ptr<>

auto_ptr as argument or return value



Should be passed as variable, not as reference
This way we create sink (argument) or source (ret. val.) of data
const auto_ptr


will not allow to transfer owned data to another auto_ptr
will not allow to assign data owned by another auto_ptr




ultimately will destruct owned data
changing owned data still ok.
good for sink
const auto_ptr &


for functions operating on owned data without changing ownership
examples: util/autoptr1.cpp util/autoptr2.cpp
auto_ptr<>

auto_ptr as a member variable


may make destructor not necessary
is safe even for exceptions thrown by a constructor


as opposed to regular pointers, since if constructor fails
then destructor is not executed
usually requires implementing copy constructor
and assignment operator

since default ones woud remove data from object being
assigned
numeric_limits<>


numeric_limits<> is a template that defines various
properties of a numerical types
member variables and methods should be used to
determine type properties at the compile time




numeric_limits<int>::digits // no. of bits for integer types
numeric_limits<int>::max() // easy to guess
…
it is implemented as a template that has
specializations for all fundamental types
Special containers

stack (LIFO queue, implemented using deque)
queue (FIFO queue, implemented using deque)
priority_queue

bitset

hash_set, hash_multiset, hash_map,
hash_multimap


(implemented using hash table instead of binary tree)
stack


header <stack>
simple LIFO queue implemented using deque











may be based on any container supporting: back(), push_back(), pop_back(),
just give 2nd template argument, eg.: stack<int, vector<int> >
just redirects own methods to deque methods to obtain LIFO queue
example: cont/stack1.cpp
push()
pop()
top()
// get the value of topmost element
// but do not remove it from stack
size()
// get the current number of elemets
empty()
// is it empty
operators: ==, !=, <, >, <=, >= // == returns 1 if size and all elements are equal
no more methods or operators
queue


header <queue>
simple FIFO queue implemented using deque












may be based on any container supporting: front(), back(), push_back(), pop_front()
just give 2nd template argument, eg.: queue<int, list<int> >
just redirects own methods to deque methods to obtain FIFO queue
example: cont/queue1.cpp
push()
pop()
back()
// get the value of element most recently push-ed
// but do not remove it from stack
front()
// get the value of element at the front of queue
// but do not remove it from queue
size()
// get the current number of elemets
empty()
// is it empty
operators: ==, !=, <, >, <=, >=
// == returns 1 if size and all elements are equal
no more methods or operators
priority_queue


header <queue>
simple priority queue implemented using vector











may be based on any container supporting: front(), push_back(), pop_front(), oper.[]
just give 2nd template argument, eg.: priority_queue<int, deque<int> >
the 3rd argument is a sort criterion (defaults to operator< )
priority_queue<int, vector<int>, greater<int> >
redirects own methods to vector methods
example: cont/pqueue1.cpp
push()
pop()
top()
// get the value of element of the greatest priority
// but do not remove it from queue
size()
// get the current number of elemets
empty()
// is it empty
no more methods or operators (no operator ==, etc.)
bitset



header <bitset>
convinient class for handling fixed size sets of bits
bitset<20> flags;
performing bit stream i/o


also to perform integer i/o in binary format


example: cont/bitset1.cpp
example: cont/bitset2.cpp
no copy constructor or assignment operator
bitset

bitset constructors
bitset<bits>::bitset()
bitset<bits>::bitset(unsigned long val)
bitset<bits>::bitset(const string &sc)
// no char* initialization, couple variants of string initialization

bitset methods and operators
size()
// return size of bitset
count()
// count ones
any()
// 1 if at least one bit set
none()
// !any()
test(size_t idx)
// is the idx-th bit set
operator==(const bitset<bits>& arg)
operator!=(const bitset<bits>& arg)
…
bitset

bitset methods and operators
set()
// set all to ones
set(size_t idx, int value=1)
reset()
// set all to zeroes
reset(size_t idx) // set idx-th to zeroes
flip()
// negate all bits
flip(size_t idx)
bitwise operators (argument size must match): ^= |= &= ^ |
bitwise shift operators (size_t argument):
<<= << >>= >>
& ~
steram operators: << >>
bool operator[] (size_t idx) const // undefined behaviour if idx out of range
bitset<bits>::reference operator[] (size_t idx) // returns object of special proxy type
// with reference type we may: =(bool), =(const reference &), flip(), operator~(), bool()
to_ulong(), to_string()