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: 
You're talking about run-time polymorphism.

This is the idea that an object can be of a class derived from the \*statically known class, so that calls to virtual member functions in the statically known class, end up in derived class implementations.

With a pointer or reference the most derived class can be different from (more specific than) the statically known class. But with a direct variable the statically known class *is* the most derived class. So there's no room for run-time polymorphism, except in calls that end up causing calls from base class member functions (in a base class member function the statically known type is that base class, different from the most derived class).

---

\*) *Statically known* class means known to the compiler without any analysis, the declared class.
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.