В этом операторе
A a1 = B();
используется конструктор копирования по умолчанию класса A, поскольку объект a1
имеет тип A.
Этот конструктор выглядит как
constexpr A( const A & );
Таким образом, только подобъект типа A
объекта класса B
копируется в объект a1
.Таблица указателей на виртуальные функции объекта a1
будет содержать указатель на собственную виртуальную функцию.
В этом объявлении
A *a = new B();
указатель a
указывает на объекттип B
, который содержит таблицу указателей на виртуальные функции, который в свою очередь содержит указатель на виртуальную функцию класса B.
Таким образом, в этом вызове
g(*a);
ссылкак объекту динамического типа B
передается (сам объект не был изменен, когда он был передан функции по ссылке).
Таким образом, внутри функции
void g(A& a) {
a.h();
}.
будет доступ к таблице указателей виртуальных функций, которая содержит указатель на виртуальную функцию класса B. Здесь новый объект класса A
не создается, поскольку исходный объект передается по ссылке.
В этом вызове
f(*a);
аргумент функции передается по значению.То есть происходит инициализация копии параметра функции, объявленной как
void f(A a) {
a.h();
}
Так что это фактически тот же случай, что и в объявлении
A a1 = B();
, рассмотренном выше.