Effective C++ item 20: Prefer pass-by-reference-to-const to pass-by-value.

By default, C++ passes objects to and from functions by value. Unless you specify otherwise, function parameters are initialized with copies of the actual arguments, and function callers get back a copy of the value returned by the function. These copies are produced by the objects’ copy constructors. This can make pass-by-value an expensive operation. If you use pass-by-reference-to-const instead of pass-by-value, it will save the overhead of making unnecessary copies.

Passing parameters by reference also avoids the slicing problem. When a derived class object is passed(by value) as a base class object, the base class copy constructor is called, and the specialized features that make the object behave like a derived class object are “sliced” off. This is almost never what you want. For example

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
class Window
{
public:
...
std::string name() const;
virtual void display() const;
};

class WindowWithScrollBars:public Window
{
public:
virtual void display() const;
};

void printNameAndDisplay(Window w)
{
std::cout << w.name();
w.display();
}

///////////////////////////////////////
// If you use like this, methods of base
// class Window will be called instead
// of derived class WindowWithScrollBars!
WindowWithScrollBars wwsb;
printNameAndDisplay(wwsb);

Reference:
“Effective C++” Third Edition by Scott Meyers.