void printNameAndDisplay(Window w) // неправильно! Параметр
{ // может быть «срезан»
std::cout << w.name();
w.display();
}Посмотрим, что случится, если вызвать эту функцию, передав ей объект WindowWithScrollBar:
WindowWithScrollBar wwsb; PrintNameAndDisplay(wwsb);
Параметр w будет сконструирован – он передан по значению, помните? – как объект Window, и вся дополнительная информация, которая делает его объектом WindowWithScrollBar, будет срезана. Внутри printNameAndDisplay w всегда будет вести себя как объект класса Window (потому что это и есть объект класса Window), независимо от типа объекта, в действительности переданного функции. В частности, вызов функции display внутри printNameAndDisplay всегда вызовет Window::display и никогда – WindowWithScrollBar::display. Способ решения проблемы «срезки» – передать w по ссылке на константу:
void printNameAndDisplay(const Window& w) // правильно, параметр
{ // не может быть «срезан»
std::cout << w.name();
w.display();
}