this dir | view | cards | source | edit | dark
top
Programming in C++
- header files in C++
- the whole class has to be in the header file (including implementation of the member functions, even private members)
- it is not a good idea to try to modify the value of a function parameter
- when using
const
and pointers together, it might get complicated
- the behavior will differ based on the
const
keyword position
- function declaration vs. definition
- declaration – in the header (hpp) file
- does not have to contain names of the parameters
- can contain default values of the parameters
- definition – in the source (cpp) file
inline
keyword
- if you insert something in a container, it is copied
const
keyword
auto&&
→ compiler will determine the best way to access the item (might even use const)
std::string
- mutable
- assignment copies the characters
- small strings may be located inside the std::string object (in some implementations)
- larger strings are stored in a dynamically allocated block owned by the std::string object
- if the appended characters can fit inside the block, they are just appended
- otherwise, a larger block is allocated and all the characters are copied there
- how (not) to share links
- value …
T
- default value defined by default constructor
- we can use
x.member
- raw (C) pointers …
T *
- undefined by default (if not global)
- it is good practice to set them as null pointer
- the instance needs to be deleted (exactly once)
- star needs to be repeated when creating multiple pointer variables
- we can use
(*x).member
or x->member
- smart pointers …
std::shared_ptr<T>
- initialized as null pointer
- we can use
x->member
- references …
T &
- must be initialized
- cannot be redirected
- we can use
x.member
- reference does not own the object, it has to be owned by someone else
- assignment replaces the value of the referenced object
- references
T &
used as an output parameter
const T &
used as an input parameter
T &&
used to steal from them
- two types of r-values
- prvalue (pure r-value)
- xvalue (result of std::move or other function/cast returning T&&)
- resolution of the overloaded function depends on the number and types of the arguments
- or, for member functions, it depends on the type of the object (whether it's modifiable or not)
- rule of five
- virtual destructor for abstract classes
- conventions for the use of references and pointers
- invalidations in containers
- modification action in sequential container invalidates…
- pointers
- references
- iterators
- associative containers
- unordered
- pointers – not invalidated
- references – not invalidated
- iterators – invalidated
- ordered
- for_each makes a copy of the functor using its copy constructor
- when calling a function, the compiler may infer its namespace from the arguments
- using virtual functions
- we need to have pointers/references to the objects to be able to call their functions virtually
- otherwise, the call is always non-virtual
- what happens if we do this?
Derived d; Base b = d;
- a copy constructor of the base class is invoked
- there exists a conversion from the derived class to the base
- as a result,
b
would be an instance of the Base class, it would contain only a subset of the data members of d
- this is called “slicing”
- casts
- virtual inheritance
- forwarding (universal) references
- compiler selects variable/parameter type according to the actual argument
auto&&
variable type
- as templated function argument
T&&
- perfect forwarding
- if we want to forward the variable to another function while keeping its original properties (l/r-value and constness), we should use
std::forward<T>(x)
- variadic templates
- example:
template<typename... TList> void f(TList&&... plist) { g(std::forward<TList>(plist)...); }
- fold expression
- traits, policies, functors, tags
- traits … used to determine properties of a type used in a template
- example: we want to find the numeric limits of the type T in the current specialization
- we may use methods like
std::numeric_limits<T>::lowest();
for that – if there exists such specialization for the type
- policies … classes used as type parameters in templates to influence the internal behavior of the template
- example: allocation policy of a container
- we want to pass a set of functions (and types…) that the container should use
- usually, the functions would be static
- but it is also possible to pass an instantiated policy as a parameter of the constructor (it would be still used as a type parameter of the template)
- alternative: to use OOP and require that the allocators implement some interface (stated using an abstract allocator) – this would be slower that the templated version