C++ Lectures
- Modern C++ 19-07-2016
- can control and have abstraction
- should depends
- Exceptions and exception safety
- weak exception safety
noexcept
- don't use any other exception specifiers
- can still use noexcept
- will force a death if things throw
- Ownership
- be careful about ownership, memleak, locks, file descriptors
- Never
- write cleanup stanzas
- idiomatic c code
- write cleanup stanzas
- RAII
- Wikipedia
- Resource Acquisition is Initialization
- Constructors acquire a resource
- Destructors clean up a resource
- folly scopeGuard
- most general form of RAII
- upon creation takes a lambda whic his called on destruction
- lambdas catches by reference
folly::FILE
is an RAII type that closes the file on destruction- Never write
delete
- Classes with business logic should compose RAII
- Ownership Semantics
- RAII => Object lifetime = resource lifetime
- Resolving ownership solves lifetime problems
- Get the ownership model of the code correct
- uniqueptr
- easy to reason about
- sharedptr
- very hard to reason about
- good when shared ownership is the correct design
- read-copy-update [wikipedia]
- Updater thread
- should I update the universe?
- creates an entirely new state
- sets the new state
- Worker threads
- shared pointers to most recent state
- whichever worker thread is last will free the previous state
shared_ptr
is not thread safe:- one thread writing into it and others reading
- need to use
std::atomic
- Updater thread
const
means object isn't modified- claiming (complete/shared) ownership means that the object is modified
- own
- direct instance
- uniqueptr
- sharedptr
- never write
new
, only in factory-only functions std::make_shared
creates a new object, and sets up the shared pointerfolly::make_unique
- Synchronization
- don't write your own
- folly
mpmcqueue
,synchronized
,futures
- make a different abstraction
- lots of basic primitives
std::atomic
- lockless programming
- mutexes are too slow
- major engineering effort
volatile
- doesn't enforce sequential consistency
- prefer
std::atomic
bool - c uses compiler intrinsics
- good for hardware directly
- Locks
- mutable: internal mutex, internal cache
- never lock and unlock
- make synchronization a first class abstraction
- Polymorphism
virtual
- dynamic polymorphism
- call out to the real classd
- fake virtual
- implemented with switch statements and enums
- static polymorphism
- choice is made by the programmer
- determined by programmer
- templates
- overloading
- actual C++ iterators
- any types that
- implement
=, !
, ++, * ,…
- templates
- good for performance
- compile times are bad, error messages
- given a statically polymorphic library, it's easy to make a dynamic version
- CRTP - curiously recurring template pattern
- type erasure
- virtual
- runtime dispatch
- can be orders of magnitude slower
- inability to inline
- dominant cost of using virtual
- std::function: dynamically polymorphic, can't inline
- lambdas are statically polymorphic
- pass lambdas directly
- templates are basically duck typing; will just punch you with a compiler error.
- Well behaved abstractions
- reference type or a value type?
- reference
- polymorphic
- data is not copyable
- reference
explicit
if you are a single argument constructor; allows for implicit conversion from argument to parent type- never two phase initialize
- have an init() after construction
- have a reset() method
- constructors
- put objects into valid states
- can't create, then throw
- is it copyable? movable?
- default to disabling copyable: eg. most RAII types are not copyable
- expensive to copy; just disable it p
- sane API - any semantic meaning to copying?
- most things are movable
- non-movable: can't be moved to one memory location to another
- mutexes
- never write your own copy constructor
- contain horribleness if you really need a copy constructor
- never write your own destructor
- mainly because you need a resource
- only for RAII type
- compose RAII types
- const correctness
- Ok
class Object { Object(Object& object) = delete; }
free function that works on views that do real work wrapper function that allocates memory, resources objects wrap this
containers are one thing, algorithms are another thing
- reference type or a value type?