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: 
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.
Basically, when you pass an object by value it's copied to an object of the destination type - at that point it *is* an object of the destination type, so there's nothing to polymorph (is that even a word?).

To use your example, `void printArea(Shape shape);`, inside the `printArea()` function the parameter `shape` *is* a `Shape` object, regardless of what object was used at the call site.