1. C++ Hints
1.1 The Golden Rules of Programming
1.2 General Design Tips
- Worry about correctness first, and efficiency later.
- Premature optimization is the root of all evil. (Knuth, et al)
- But don't make bad designs that preclude efficiency.
- Write code that is easy to understand and debug.
- Write Small, Testable pieces of code.
- Write as little code as possible. Reuse wherever you can.
1.3 Design for robustness and debuggability
- Yes, you can design your code so that it is easier to debug! Its a
conscious choice, and you might need to make tradeoffs.
- Check for errors before they occur
- Avoid objects that can be in invalid states
- Failure of a constructor can cause problems - no way to signal an
error, might return an invalid object.
- Error check before constructors
- Use factories rather than constructors (for heap objects)
- Document (and have tests for) preconditions and invariants.
1.4 Class Design and Object Oriented Programming
- Group Data that Goes Together
- Make classes minimal
- Functions that use objects rather than methods (better preserve
privacy issues, keep classes clean, ...). Big Java vs. C++ thing.
- Less to understand at core - keep independent pieces independent.
- Write accessors if they are clearer, or if you really want read-only
- Choose data structures wisely.
- Be careful about automatic copying and conversion - the compiler
might not do what you want!
1.5 Let the Compiler Catch your Bugs!
- No warnings - ''your code should always compile with no
warnings.'' Even if you know it isn't a problem, some new warning
might get lost in the middle. Somethings that seem inoccuous might
really be a problem
- Let the type checker catch your bugs whenever possible! This
usually means thinking about your code to make the type system be
const whenever it is possible, as much as possible, and
correctly. If nothing else, it is good documentation!
- Avoid casts as much as possible
- Use classes to pass long argument lists
- Default constructors can be helpful here
1.6 Memory Management
- Understand the different types of memory
- Heap Allocated
- Know who is responsible for memory - make good comments about this!
- Avoid copying heavy objects
- Efficiency in parameter passing
- Slicing and aliases
- Declare variables when they are used, in the tightest scope
- Use auto variables for short lived objects only. (should not want to
survive the scope)
- Understand how vectors work, and why/when to use them
1.7 C++ isms
- Avoid fancy language features unless you understand them, and really
- Avoid macros.
- Prefer new/delete to malloc/free
- be careful returning &
1.8 Debugging and Testing
- Design good test cases
- simple examples that are easy to see what is going on
- things with known answers
- excersize all code paths - get coverage
- consider boundary conditions - and make examples that test them
- try the easy cases first - if your program doesn't work on these,
there's no point going on to the harder cases
- Understand what your program should be doing - and devise checks to
make sure it is working as you expect.
- Avoid the "million monkey" style of debugging (randomly permute code
until it works).
A wrapper around the C I/O library (we're stuck with its design) that
tries to only handle the most common and important case.
Designed to avoid "accidents":
- You always will have a pointer to one - not a constructor
- Avoids object copies (what does it mean to copy the image? deep or
- Avoids failures in the constructors
- If you have a valid pointer to one, you should have a valid image
- just check for a NULL pointer - you don't need to check inside
Very Minimalist class - just provides the storage. All operations on
it should be "external" (functions that use it).
Always has an alpha channel
- you'll learn about alpha later
- its premultiplied alpha (again, you'll learn about it later)
- need to have an extensible set of functions. don't want to have a
big long list (a case statement, or lots of ifs)
- want to keep functions independent
- want to have common parsing code
The Command concept:
- want a unified interface to all commands
- each takes different arguments
- pass the entire command line (or a list of the arguments)
- do some of the parsing work ahead of time. (this is a place where
the design is a bit weak - too much of the parsing happens in the
- why not just functions? (why the command class)
- don't want to keep a table (which you'd have to manually update)
- don't want 2 versions of the code (give away version, and complete
- Command class gives a way of automatically creating the list using
global constructors and a linked list
The Context class:
- concept from programming languages
- environment - probably the more correct term
- table of the local variables (or everything in scope)
- probably more like a register file
- store the values of the variables
- 26 of them
- each can store an image (but may have no image in it)
- memory management on read/write