Question: I'm a Java programmer and recently started studying C++. I'm confused by something.

I understand that in C++, to achieve polymorphic behavior you have to use either pointers or references. For example, consider a class `Shape` with an implemented method `getArea()`. It has several subclasses, each overriding getArea() differently. Than consider the following function:

```
void printArea(Shape* shape){
    cout << shape->getArea();
}

```

The function calls the correct `getArea()` implementation, based on the concrete `Shape` the pointer points to.

This works the same:

```
void printArea(Shape& shape){
    cout << shape.getArea();
}

```

However, the following method does not work polymorphicaly:

```
void printArea(Shape shape){
    cout << shape.getArea();
}

```

Doesn't matter what concrete kind of `Shape` is passed in the function, the same `getArea()` implementation is called: the default one in `Shape`.

I want to understand the technical reasoning behind this. Why does polymorphism work with pointers and references, but not with normal variables? (And I suppose this is true not only for function parameters, but for anything).

Please explain the technical reasons for this behavior, to help me understand.

Answer: 
The answer is copy semantics.

When you pass an object by value in C++, e.g. `printArea(Shape shape)` a copy is made of the object you pass. And if you pass a derived class to this function, all that's copied is the base class `Shape`. If you think about it, there's no way the compiler could do anything else.

```
Shape shapeCopy = circle;

```

`shapeCopy` was declared as a `Shape`, not a `Circle`, so all the compiler can do is construct a copy of the `Shape` part of the object.
When `void printArea(Shape shape)` is called, your object is copied into a brand new `Shape` on the stack. The subclass parts are not copied. This is known as [object slicing](http://en.wikipedia.org/wiki/Object_slicing). If the base-class object is not legit (e.g. it has pure virtual functions in it), you can't even declare or call this function. That's "pass by value" semantics; a copy of the passed-in object is supplied.

When `void printArea(Shape& shape)` is called, a reference to your `Circle` or `Rectangle` object is passed. (Specifically, a reference to the `Shape` part of that object. You can't access the `Circle`- or `Square`-specific members without casting. But virtual functions work correctly, of course.) That's "pass by reference" semantics; a reference to the original object is passed in.