В первом примере вы вызываете метод через указатель:
p->Method();
В этом случае 'p' является указателем на Parent, и C ++ знает, что у Parent есть v-таблица, поэтому он использует ее для поиска фактического метода для вызова, который в данном случае, как вы утверждаете, равен Child::Method()
потому что, когда C ++ находит v-таблицу, он находит v-таблицу «нового» дочернего экземпляра.
Во втором примере вы вызываете метод для экземпляра:
p.Method();
В этом случае 'p' является экземпляром Parent, а C ++ предполагает, что он знает, что точный тип действительно является 'Parent', и поэтому он вызывает Parent::Method()
, не просматривая никаких v-таблиц.
Я только что проверил это с VS2008, и выше на самом деле то, что происходит, и нет срезов , однако, я думаю, что срез действительно происходит но вы бы увидели это только во втором случае, если бы сделали:
Parent& q=p;
q.Method();
Тогда я вижу: Parent :: Method () в процессе печати. q.Method()
должен быть виртуальный вызов, но он может найти только v-таблицу для Parent.