Scott Meyers Training Courses
Effective C++ Programming
This intensive seminar, based on material in Meyers' landmark books (Effective C++, More Effective C++, and Effective STL), explains how to use C++ effectively: how to create libraries and programs that are correct, efficient, portable, maintainable, and extensible.
Course Highlights
Participants will gain:
- Knowledge of the rules of thumb applied by expert C++ programmers as they design and implement software systems.
- An understanding of the proper application of C++'s many features, e.g., member and non-member functions, templates, inheritance, virtual and non-virtual functions, namespaces, etc.
- Insights into how to effectively combine language features to achieve desired behavior.
Each attendee will also receive a copy of Effective C++, Third Edition.
Who Should Attend
Systems designers, programmers, and technical managers involved in the design, implementation, and maintenance of production libraries and applications using C++. Participants should already know the basic features of C++ (e.g., classes, inheritance, virtual functions, templates), but expertise is not required. Every C++ programmer will come away from this seminar with useful, practical, proven information.
Format
Lecture, question/answer, and group design and problem-solving exercises. There is no hands-on programming, but participants are welcome to use their computers to experiment with the course material as it is presented.
Length
One full week (six to seven lecture hours per day).
Detailed Topic Outline
- const:
- The value of const
- const, pointers, string literals, and indirection
- const, pass-by-value, and return-by-value
- bitwise const vs. conceptually const member functions
- Casting away const
- const and object lifetimes
- const vs. #define vs. "the enum hack"
- Resource Management:
- Use objects to manage resources
- Resource acquisition is initialization (RAII)
- std::auto_ptr
- std::tr1::shared_ptr
- TR1 and Boost
- Think carefully about copying behavior in resource-managing classes
- Store resources in objects in standalone statements
- Use objects to manage resources
- Constructors, Destructors, and Assignment Operators:
- Know what functions C++ silently writes and calls
- Explicitly disallow use of implicitly generated member functions you
don't want:
- Declaring functions private
- Inheriting from a base class declaring them private
- List members in an initialization list in declaration order
- Handle copying in classes with pointers:
- Handling the functions yourself
- Using resource-managing objects
- Make destructors virtual in base classes
- Virtual functions and object layout
- Prevent exceptions from leaving destructors
- Handle assignment to self in operator=:
- The problem of aliasing
- Checking for assignment to self
- Using resource-managing objects
- Self-assignment and exception-safety
- Assign to all data members in operator=:
- Partial assignments
- The problem of inheritance
- The copy construction analogue
- Further Class Design:
- Be wary of user-defined conversion functions
- Avoid returning "handles" to internal data
- Prefer non-member non-friend functions to member functions:
- The value of encapsulation
- How removing member functions increases class encapsulation
- Using namespaces to associate classes and functions
- Declare non-member functions when type conversions should apply to all parameters
- If you overload binary operator op, overload op= too
- Choose carefully between function overloading and parameter defaulting
- Guard against potential ambiguity
- Inheritance And Object-oriented Design:
- Make sure public inheritance models "isa"
- Inheritance and intuition
- Runtime vs. compile-time error detection
- Inheritance and substitutability
- Differentiate between inheritance of interface and inheritance of
implementation:
- The meaning of pure virtual functions
- The meaning of "impure" virtual functions
- The meaning of nonvirtual functions
- Never redefine an inherited nonvirtual function
- Avoid casts down the inheritance hierarchy
- Avoidance techniques
- Using RTTI for safe downcasting
- dynamic_cast
- typeid
- RTTI and tr1::shared_ptrs
- Model "has-a" or "is-implemented-in-terms-of" through containment
- Use private inheritance judiciously
- Use multiple inheritance judiciously:
- MI and ambiguity
- Virtual base classes
- Initialization
- Dominance
- Software evolution and MI
- Understand implicit interfaces and compile-time polymorphism:
- Explicit interfaces
- Implicit interfaces
- Making implicit interfaces explicit
- Runtime vs. compile-time polymorphism
- Make sure public inheritance models "isa"
- Concepts and Architecture of the STL:
- Arrays and pointers, half-open ranges
- Generalizing pointers to iterators
- Generalizing arrays to sequences
- Algorithms
- Conventions and extensibility
- Function objects
- Overview of standard and TR1 containers
- The behavior of remove
- Efficiency:
- The 80-20 rule and program profiling.
- Language issues:
- Eliminating unnecessary temporary objects:
- Pass by reference-to-const instead of by value.
- Defer object definitions as long as possible.
- Prefer initialization to assignment in constructors.
- Consider overloading to avoid implicit type conversions.
- Consider using op= instead of op.
- Facilitate the return value optimization.
- Consider a more C-like design.
- Don't try to return a reference when you must return an object:
- Returning a reference to a local object.
- Returning a reference to a heap-allocated object.
- Returning a reference to a local static object.
- The pros and cons of inlining:
- Inlining and compiler optimization.
- Automatic inlining.
- Linktime inlining.
- When custom memory managers make sense.
- Eliminating unnecessary temporary objects:
- Library issues:
- Use reserve to minimize memory reallocations in
vector and string.
- Using "the swap trick" to perform "shrink to fit."
- Prefer range member functions to single-element versions for sequence containers.
- Prefer function objects to functions.
- Why sort is typically faster than qsort.
- Why sorted vectors can be superior to
sets and maps for lookup-intensive applications.
- std::binary_search vs. std::lower_bound vs. std::equal_range
- STL containers based on hash tables.
- Use reserve to minimize memory reallocations in
vector and string.
- Reference Counting:
- A reference-counted string implementation.
- How changing the implementation changed the interface.
- How threading issues can turn an optimization into a pessimization.
- Additional Efficiency Topics
- Programming with Exceptions:
- EH 101:
- try, throw, catch, stack unwinding
- Exception specifications
- Function try blocks
- The real challenge of programming with exceptions
- Strive for exception-safe code
- Definition of "exception-safe"
- The basic, strong, and nothrow guarantees
- Exception specifications and exception-safety guarantees
- Approaches to the strong guarantee
- Careful statement ordering
- Copy and swap
- Dependencies among exception-safety guarantees
- Exercise: making exception-unsafe code exception-safe
- Preventing resource leaks in constructors
- The differences between passing parameters to functions and moving exceptions from throw sites to catch clauses.
- Understanding the performance costs of exception handling.
- EH 101:
- Epilogue: Programming In The Future Tense
- Further Reading
For more information on this course, contact Scott directly.
