Ответ 1
Это удивляет немало людей, но аргумент по умолчанию (или аргументы, если вы указали более одного) на основе статического типа (тип, на который объявлен указатель), а не динамический тип ( тип объекта, к которому он в настоящее время указывает).
Как таковой, поскольку вы используете Base *bp
, используются аргументы по умолчанию, объявленные в Base
, независимо от того, указывает ли bp
на Base
или Derived
.
Если вам небезразлично, почему это так: по крайней мере, в типичной реализации аргументы по умолчанию фактически обрабатываются во время компиляции. Компилятор видит, что вы вызвали Display
без предоставления аргумента, и что Display
имеет один аргумент со значением по умолчанию. Поэтому, когда он генерирует код для этого вызова, генерируется код для передачи заданного по умолчанию значения. В то время у него нет возможности даже догадываться, указывает ли указатель на некоторый производный тип, когда происходит вызов, поэтому все, что он может сделать, это генерировать код на основе статического типа. Хотя это не так, когда он генерирует код для выполнения вызова, даже возможно, что он может работать на производном классе, который еще не был спроектирован или написан, поэтому используйте значение, указанное в этом производном классе было бы невозможно.