переменная b на самом деле ссылается на тот же экземпляр, что и a. В случае семантики значения мы бы имели копирование значения a в b, после чего это были бы совершенно разные объекты. Думаю, для многих новичков является сюрпризом, когда они обнаруживают, что при изменении a одновременно меняется и b.
Согласен.
В процессе присваивания с самим первоначальным экземпляром ничего не происходит. Поэтому говорить о том, что у данного экземпляра появился еще один тип, не совсем корректно. Появилась лишь ссылка b, значением которой является ссылка на a, преобразованная к типу "ссылка на b".
Похоже, ты меня не понял. Я не говорил "появляется ещё один тип", я говорил "есть ещё один тип" - это устанавливается не во время исполнения, а на уровне семантики исходного кода. С другой стороны, отказывая в множестве типов значению, ты так или иначе переносишь это на ссылки. Каким образом ссылка типа A "сохраняет" в себе факт преобразования к типу B? Если уж обращаться к техническим подробностям реализации, то RTTI хранится не в ссылке, а в самом объекте. И при работе с объектом, когда к нему обращаются через ссылку, не происходит никаких "преобразований" каждый раз, просто структуры объектов разных типов, находящихся в отношении AKO между собой, чисто технически совпадают так, что с A можно работать как с B без всяких преобразований. Именно это я называю множественностью типов у значения (в отличие от единственности типа у переменной).
Эта вся путаница из-за медвежьей услуги с неявным разыменованием ссылок. В кондовом С++ вряд ли кто-нибудь сказал бы, что если A наследует от B, то A - это B, хотя бы по той причине, что нет неявного преобразования A к B. А вот тип указателя на B запросто можно неявно привести к типу указателя на A. Но указатель и то, на что он указывает, там совершенно разные сущности.
Нет, всё равно RTTI хранится в объекте, а не в переменной. Да, в C++ по умолчанию присваивание означает копирование значения за исключением объявления ссылки. Причём ссылка в C++ - это не указатель, так как хранит не адрес, а само значение. Никакого преобразования не происходит.
A a;
a.m(); // A.M
B &b = a;
b.m(); // A.M - потому что тот же объект
B b1 = a;
b1.m(); // B.M - другой, вновь созданный объект типа B, полученный копированием из a.
В C# для ссылочных типов присваивание работает как для b, а для нессылочных типов - как для b1. И это неочевидно на уровне исходного кода
.
По моему всё просто, такая запись:"А а" означает что мы объявляем ссылку на объект типа А или всех его подклассов, а если А - интерфейс то
то объект всех классов которые его реализует. Вот и всё.
Это эквивалентно множественности типов ссылок и единственности типа значения. Такая интерпретация оставлят "за бортом" невиртуальные методы - их выбор определяется типом ссылки, а если типов много, то непонятно, что выбрать. Причём для невиртуальных методов RTTI не используется.
С другой стороны, это моё утверждение можно развернуть наоборот: непонятно, какой из виртуальных методов выборать, если у значения множество типов. Тип значения определяется при конструировании объекта и сохраняется в RTTI. На это я так скажу: значение определяется типом конструктора (технически именно в этот момент заполняется таблица виртуальных функций) - не у значения появляется тип, а появляется значение, соответствующее (тоже чисто технически на уровне общности структуры объекта) одному или более типам (или быть отнесено к нескольким типам, проинтерпретировано разными типами) и содержащее такие методы, которые определяются типом конструктора.