c касти в стилі або касти в стилі c ++


21

Отже, чим ви користуєтесь?

int anInt = (int)aFloat;

або

int anInt = static_cast<int>(aFloat);
// and its brethren

І, що ще важливіше, чому?

Відповіді:


45

По-перше, зрозумійте, що ці рядки не рівнозначні .

int* anInt = (int*)aFloat; // is equivalent to

int* anInt = reinterpret_cast<int*>(aFloat); 

Тут відбувається те, що програміст просить компілятора зробити все можливе, щоб зробити акторський склад.

Різниця важлива, тому що за допомогою static_cast буде запропоновано лише базовий тип, який "безпечно" перетворити в, де reinterpret_cast перетворить у що завгодно, можливо, просто зіставивши потрібний макет пам'яті над пам'яттю даного об'єкта.

Отже, оскільки "фільтр" не той самий, використання конкретного кадру є більш зрозумілим і безпечним, ніж використання C-ролика, якщо ви покладаєтесь на компілятор (або імпульс виконання, якщо ви використовуєте динамичний_cast), щоб сказати вам, де ви щось зробили не так , за допомогою Avong C cast і reinterepret_cast.

Тепер, коли це зрозуміло, є інша річ: static_cast, reinterpret_cast, const_cast та динамичний_cast легше шукати .

І кінцевий момент: вони некрасиві . Цього хотіли. Потенційно невдалий код, запахи коду, очевидні "хитрощі", які можуть створювати помилки, простіше відстежувати, коли це пов'язано з некрасивим виглядом. Неправильний код повинен бути некрасивим .

Це "задумом". І це дозволяє розробнику знати, де він міг би зробити щось краще (цілком уникаючи ролі, якщо не дуже потрібна) і де це добре, але це "задокументовано" в коді, "позначивши" його як потворне.

Вторинною причиною введення нового акторського складу було те, що ролі в стилі С дуже важко помітити в програмі. Наприклад, ви не можете зручно шукати касти за допомогою звичайного редактора або текстового процесора. Ця майже невидимість у ролях у стилі С особливо прикрою, оскільки вони настільки небезпечні. Потворна операція повинна мати потворну синтаксичну форму. Це спостереження було частиною приводу вибору синтаксису для нової кастингу. Наступною причиною було те, що касти в новому стилі відповідали позначенням шаблону, щоб програмісти могли писати власні касти, особливо касти, що перевіряються під час роботи.

Можливо, оскільки static_cast такий некрасивий і настільки важкий для набору, ви, швидше за все, подумайте двічі, перш ніж використовувати його? Це було б добре, тому що в сучасних мовах C ++ в основному можна уникнути ролі.

Джерело: Bjarne Stroustrup (C ++ Creator)


2
Я би спростував це, якби у мене було ще кілька пунктів, але, на жаль, не можу. Касти в стилі c НЕ еквівалентні reinterpret_cast. Розглянемо reinterpret_cast<int>(double);. Це цілком можливо, щоб запустити дубль до int з кестом у стилі c, але це неможливо зробити за допомогою reinterpret_cast. Я бачу, Тимбо вже вказав на це, і ви сказали, що це виправите, але через чотири роки це залишається неправильним. Я б все-таки оголосив вас, якби це було виправлено, оскільки є цілком обґрунтовані причини, що потрібно використовувати акторський склад. Ось найкраща відповідь: stackoverflow.com/a/332086/3878168
Yay295

36

C ++ касти є більш обмежуючими (тому краще висловлюйте свої наміри та полегшуйте розгляд коду тощо). Їх також набагато простіше шукати, якщо вам коли-небудь доведеться.


10
... і вони швидше роблять те, що ви задумали. ;-)
Макке

7
І їх набагато більше набирати, що дає вам ще одну причину просто виправити свої типи, не вимагаючи жодних ролей.
Майкл Коне

7
І вони некрасиві як особливість, роблячи очевидним, де в коді можуть бути пункти покращення або особливі випадки, які можуть вимагати документації. - edit: Ух, я щойно виявив, що відповів і на це запитання! XD
Klaim

Тепер чому я хотів би їх шукати?
Дедуплікатор

@Deduplicator Існує багато причин, з яких ви можете знати, де в ролі базування кодів відбуваються касти. Наприклад, при полюванні на помилок, які можуть бути пов'язані з кастингом (зокрема, при розробці крос-платформ).
Клаїм

13

Варіант С: акторський склад "С ++", оскільки він не відрізняється від конструкції:

int anInt = int(aFloat);

або навіть:

int anInt(aFloat);

Що ж, окрім цих тривіальних випадків із примітивами, які добре розуміються, я вважаю за краще використовувати x_cast <> s над кастами в стилі C. Три причини:

  • Вони більш вузько визначають операцію, яку намагався виконати програміст.

  • Вони можуть виконувати дії, які передавати у стилі С не можуть (особливо у випадку з динамічним_кастом <>, який може перетинатися через гілки ланцюга з множинним успадкуванням).

  • Вони некрасиві . Вони голосно заявляють, що програміст працює проти системи типу. У цьому випадку це добре .


7

Якщо ви пишете код на C, використовуйте команду C. Якщо ви пишете на C ++, використовуйте команду C ++.

Хоча більшість кастингу порушує належну безпеку типу, C ++ є більш обмежуючими, і тому ви трохи менше небезпечні для типу, ніж ви б зі складу C.

Я можу терпіти, що хтось використовує (T *) NULL, хоча змусити перевантажити ...


7

У мене є кілька правил щодо кастингу в стилі C / C ++:

  1. Застосування const завжди повинно використовувати a const_cast. З зрозумілих причин. На жаль, моє правило про заборону застосування const, яке спричиняє клавіатуру вгору та зламати палець програміста, не було затверджено.
  2. Будь-який з шенаніганів у стилі біт-маніпуляції, який програмісти отримують під час сходу до металу, повинен використовувати reinterpret_cast. Це насправді такий склад, якого у C немає: зробіть вигляд, що ці біти цілих чисел є дійсно бітами поплавця. Це дозволяє уникнути неприємних ситуацій, як (int)(*(int*)(&floatVar)).
  3. Якщо ви введете слова " dynamic_cast", зупиніть і переоцініть свою ієрархію та дизайн поліморфних класів. Продовжуйте переоцінювати дизайн ієрархії класу, поки ви не зможете видалити ці слова.
  4. Не турбуйся static_cast.

Міркування №4 - це просто те, що це не має значення. Обставини, які не вписуються в інші правила, або очевидні, або дуже низькі. Для добре зрозумілого перетворення простих типів, таких як int-to-float, не повинно бути потрібен спеціальний синтаксис. І якщо ти в глибоких, потворних кишках чогось, ну, ти в глибоких, потворних кишках чогось. Не потрібно звертати увагу на той факт, що "тут є дракони", оскільки зуби, кігті та вогонь вже дуже віддавали його.


1
dynamic_castє ідеально правильним інструментом. Признаюсь, дуже рідко, але це далеко не сатана таких речей, як глобальні змінні. Однак, перш за все, я звернувся до вас, оскільки ви не відповіли на запитання , що стосується того, чи використовуєте ви касти в стилі С.
DeadMG

2
@DeadMG: Я говорив про касти в стилі C. Останній абзац виправдовує касти в стилі C на користь static_cast.
Нікол Болас

"На жаль, моє правило про заборону застосування const, що призводить до того, що клавіатура охоплює руку і ламає палець програміста, не було схвалено". У технічному плані компілятор фактично законний, щоб це відбулося. Як законно для компілятора, щоб змусити демонів літати з вашого носа .
Фарап

4

Як зазначається у вищезазначених публікаціях, C ++ (статичний) амплуа на практиці трохи безпечніший.

Можливо, було б розумно знайти додаткову інформацію про різні види кастингу та їхні плюси та мінуси.

Просто, щоб мати більше інформації про те, чому. .

http://en.wikipedia.org/wiki/Static_cast

http://en.wikipedia.org/wiki/Dynamic_cast

http://en.wikipedia.org/wiki/Reinterpret_cast


3

Це дійсно залежить від того, якою мовою я працюю, оскільки ви знаєте, що вони говорять: У Римі говорять по-римськи. Отже, якщо я програмую на C, я намагаюся використовувати функції C до максимуму, але якщо я програмую на C ++, я продовжую і використовую функції C ++ до максимуму, навіть якщо деяким людям такий підхід не подобається, вони кажуть, що це робить код "менш портативним", я кажу, що мені все одно, я перебуваю на C ++ і програмую на C ++, і мені потрібен повністю сумісний C ++ компілятор, щоб компілювати код, інакше я працював би з чимось іншим на першому місці.


Насправді це не працює, намагаючись використовувати
ролі

3

static_cast і т. д. були винайдені через проблеми з кастами стилю C при використанні в шаблонах. Якщо ви пишете шаблон або якщо пізніше код може бути перетворений у шаблон, корисно використовувати касти в стилі C ++. Причина полягає в тому, що літери стилю C ++ краще виражають наміри, тому вони дадуть очікувані результати в тих випадках, коли касти в стилі С будуть робити неправильно (з урахуванням конкретних типів як параметрів шаблону).

Крім цього, я кажу, що використовуйте касти в стилі C ++, якщо у вас є конкретна проблема, яка потребує їх - динамічний_cast є найпоширенішим, але навіть це, мабуть, не щодня.

Все що завгодно, а також акторський стиль у стилі C може бути дещо менш затрудненим та сприяти читанню, а може й не залежно від того, наскільки читач знайомий із цим стилем акторської творчості в наші дні. На мій погляд, це не дуже важливо, головним чином, особисті переваги, хоча не дивуйтеся, якщо деяким людям не подобається стиль C.

Заключна примітка - якщо вам потрібно стільки ролей, що це велика справа, ви, ймовірно, робите щось інше не так. У деяких випадках є винятки, але більшості кодів високого рівня не повинно бути багато (якщо вони є).

Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.