Ви позначили це трьома мовами, і відповіді дійсно сильно відрізняються між трьома. Обговорення С ++ більш-менш передбачає обговорення C-ролей, що дає (більш-менш) четверту відповідь.
Оскільки це той, про який ви прямо не згадали, я розпочну з C. C Casts має ряд проблем. Одне полягає в тому, що вони можуть робити будь-яку з кількох різних речей. У деяких випадках акторський склад не робить нічого, крім того, щоб сказати компілятору (по суті): "заткнись, я знаю, що я роблю" - тобто гарантує, що навіть коли ти перетвориш, що може спричинити проблеми, компілятор не попередить вас про ці потенційні проблеми. Так, наприклад, char a=(char)123456;. Точний результат цієї реалізації визначений (залежить від розміру та підписаностіchar), і, за винятком досить дивних ситуацій, мабуть, це не корисно. C-касти також відрізняються тим, чи є вони чимось, що відбувається лише під час компіляції (тобто ви просто розповідаєте компілятору, як інтерпретувати / обробляти деякі дані), або щось, що відбувається під час виконання (наприклад, фактичне перетворення з подвійного в довго).
C ++ намагається впоратися з цим хоча б певною мірою шляхом додавання декількох "нових" операторів ролях, кожен з яких обмежений лише підмножиною можливостей C-акторів. Це ускладнює (наприклад) випадкове здійснення конверсії, якої ви насправді не мали наміру - якщо ви лише маєте намір відмовитись від жорсткості на об'єкті, ви можете використовувати const_castі бути впевненим, що єдине, на що це може вплинути, - чи об'єкт знаходиться const, volatileчи ні. І навпаки, a static_castне дозволяється впливати на те, чи є об'єкт constчиvolatile. Коротше кажучи, у вас є більшість однакових типів можливостей, але вони класифіковані, так що один склад може, як правило, робити лише один вид перетворення, де один склад в стилі С може зробити дві або три перетворення за одну операцію. Основним винятком є те, що ви можете використовувати dynamic_castзамість а static_castпринаймні в деяких випадках, і, незважаючи на те, що вони написані як " dynamic_cast, це дійсно закінчиться як" static_cast. Наприклад, ви можете використовувати dynamic_castдля переходу вгору або вниз по ієрархії класів - але ієрархія класів "вгору" завжди безпечна, тому це може бути зроблено статично, тоді як ієрархія "вниз" не обов'язково безпечна, тому це робиться динамічно.
Java та C # набагато більше схожі між собою. Зокрема, для обох кастинг - це (практично?) Завжди операція, що виконується. Що стосується операторів лиття C ++, це, як правило, найближче до a dynamic_castз точки зору того, що реально робиться - тобто, коли ви намагаєтеся передати об'єкт до якогось цільового типу, компілятор вставляє перевірку часу, щоб побачити, чи дозволена ця конверсія , і киньте виняток, якщо це не так. Точні деталі (наприклад, ім'я, яке використовується для винятку "bad cast") відрізняються, але основний принцип залишається здебільшого схожим (хоча, якщо пам'ять слугує, Java робить касти, застосовані до кількох необ'єктних типів, таких як intнабагато ближче до C касти - але ці типи використовуються досить рідко, щоб 1) я цього точно не пам’ятаю, і 2) навіть якщо це правда, все одно це не має великого значення).
Якщо дивитися на речі загалом, ситуація досить проста (принаймні IMO): акторський склад (очевидно, достатньо) означає, що ви перетворюєте щось з одного типу в інший. Коли / якщо ви це зробите, то виникає питання "Чому?" Якщо ви дійсно хочете, щоб щось було певного типу, чому ви не визначили це саме таким типом? Це не означає, що ніколи не виникає причин проводити таке перетворення, але коли б це трапилося, слід підказати питання про те, чи можна було переконструювати код, щоб правильний тип використовувався протягом усього часу. Навіть, здавалося б, нешкідливі перетворення (наприклад, між цілим числом і плаваючою точкою) слід розглядати набагато ретельніше, ніж зазвичай. Незважаючи на їх уявленняподібність, цілі числа дійсно повинні використовуватися для "підрахованих" типів речей і плаваючої точки для "вимірюваних" видів речей. Ігнорування розрізнення - це те, що призводить до деяких шалених тверджень на кшталт "середня американська родина має 1,8 дитини". Хоча ми всі бачимо, як це відбувається, факт полягає в тому, що жодна сім'я не має 1,8 дитини. Вони можуть мати 1 або вони можуть 2 або вони можуть мати більше, але ніколи 1,8.