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()
© Copyright 2026 Paperzz