ostream & operator<<(ostream & os, Pupil & p) 这个操作符重载,对应的参数是 Pupil&
os << (const Pupil &)s; 这个调用传递的是const Pupil&
const Pupil& 不能自动转换为 Pupil&,
所以你肯定还有一个操作符重载 ostream & operator<<(ostream & os, const Person & p)
const Pupil& 可以自动转换为 const Person&, 所以调用的是这个操作符
问题不是出在派生类引用转换为基类引用上。而是出在函数/操作符的参数类型匹配上。