As a general rule, you should pass POD types by value and complex types by const reference.
That said, a good place where you pass complex types by value is where you would need a copy of the object inside the function anyway. In that case, you have two choices:
pass the argument as a const reference and create a local copy inside the function
pass the argument by value (the compiler creates the local copy).
The second option is generally more efficient. For an example, see the copy&swap idiom.