#include <stdio.h> struct a_t { virtual void vproc() { printf("a_t\n"); } void print() { vproc(); } } aa; a_t &a0=aa,*a1=&aa; struct b_t : a_t { virtual void vproc() { printf("b_t\n"); } } bb; int main() { a0=bb; a1=&bb; a0.print(); // -> a_t - это нормально? a1->print(); // -> b_t return 0; }
в выражении a0 = bb происходит присваивание не ссылки, а объекта, который при этом приводится (неявно) к типу a_t. То есть, по аналогии, если написать: Код (Text): ... *a1 = bb; a1->print(); то получим опять-таки a_t
Да чето затормозил a0=bb; тож самое что aa=bb; просто думал что и виртуальные функции в аа замещаются. *a1 = bb; a1->print(); // извините но b_t
Хотя не тоже самое (если чето добавить в а_t) ; ; { ; a0=bb; ; @1: mov eax,dword ptr [_a0] mov edx,dword ptr [_bb+4] mov dword ptr [eax+4],edx ; ; aa=bb; ; mov ecx,dword ptr [_bb+4] mov dword ptr [_aa+4],ecx
green5 Хех... а и правда остается понять почему, ведь код по сути должен быть идентичен a0=bb; Архизабавно! Код (Text): int main() { a0=bb; a1=&bb; a0.print(); a1->print(); *a1=bb; a1->print(); return 0; } дает на выходе Код (Text): a_t b_t b_t а если вот так: Код (Text): int main() { a0=bb; a1=&aa; << извращаемся a0.print(); a1->print(); *a1=bb; a1->print(); return 0; } то получаем: Код (Text): a_t a_t a_t Вообще, конечно код очень опасный и не то, чтобы корректный, но тем не менее не противоречащий стандарту и вообще - чего бы это значило?
Присваивание Код (Text): *a1=bb приводит к копированию общих полей a_t и b_t, но без копирования vtable ptr. Если a1 перед этим указывал на объект типа b_t, то в результате получится тот же объект b_t, с модифицированной a_t-частью, но с сохранением всего остального, в т.ч. и vtptr. В общем случае делать так, конечно, не стоит - возможно нарушение целостности объекта.
Я когда не знаю что делать, пишу логирование сообщений в конструкторах, деструкторах и операторах копирования, присваивания обьектов и смотрю что вообще за каша получилась. Может стоит попробовать? Я вам обещаю, все сразу прояснится (: А пока смотрим и медитируем.
Ну с логированием далеко не уедешь, но все равно както не по себе с этими reference, вот и использовать их тока при передаче параметров
Да и код думаю не коррректный просто компилятор не отсекает это типа: int &a0=aa; ... a0=bb; // нельзя, а0 зарезервирован за аа
green5 Почему нельзя? Просто в первом случае - это инициализация, а во втором - присваивание. Для ссылок - принципиально разные операции. Аналог в указателях будет выглядеть так: int const* a0 = &aa; ... *a = bb;