Яка різниця між кастингом у стилі static_cast <> та C?


Відповіді:


217

Уривки стилів C ++ перевіряються компілятором. Касти в стилі C не є і можуть провалюватися під час виконання.

Крім того, касти в стилі c ++ можна легко знайти, тоді як шукати касти в стилі c дуже важко.

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

При написанні C ++ я завжди завжди використовую C ++ над стилем C.


67
Єдині касти, які можуть вийти з ладу під час виконання, - dynamic_casts.
Р. Мартіньо Фернандес

12
C ++ reinterpret_cast <T> (U) може вийти з ладу під час запуску майже так само, як може робити і кастинг стилю C, і всі вони сильно відрізняються від того, як відмовляє динамічний_cast <T> (U).
Крістофер Сміт

20
˗1 нормальний вміст C (int)somethingне може вийти з ладу - або ви потрапляєте до int, або помилка компілятора.
Томаш Зато - Відновіть Моніку

2
Чи можете ви детальніше пояснити, чому в C ++ ролях можна шукати легше, ніж на C?
Мінь Тран

3
@MinhTran Для стилю C ++ ви можете шукати ключове слово "лити" через вихідні файли. Але хочете, чи могли б ви зробити з кастингами в стилі c?
huangzonghao

176

Коротше кажучи :

  1. static_cast<>() дає змогу перевіряти час компіляції, C-Style cast не робить.
  2. static_cast<>() є більш читабельним і його легко помітити в будь-якому місці всередині вихідного коду C ++, C_Style cast is'nt.
  3. Наміри передаються набагато краще, використовуючи ролі C ++.

Більше пояснення :

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

char c = 10;       // 1 byte
int *p = (int*)&c; // 4 bytes

Оскільки це призводить до того, що 4-байтовий покажчик (вказівник на 4-байтовий тип даних) вказує на 1 байт виділеної пам'яті, запис у цей покажчик або спричинить помилку виконання, або замінить деяку суміжну пам'ять.

*p = 5; // run-time error: stack corruption

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

int *q = static_cast<int*>(&c); // compile-time error

Ви також можете перевірити цю сторінку, щоб отримати додаткові пояснення щодо C ++ ролях: Натисніть тут


17
Я думаю, що замість "4-байтового вказівника" ви мали на увазі "покажчик на 4-байтний тип даних"
iheanyi

але це дозволяє int q = static_cast <int> (c);
TonyParker

3
@TonyParker Це тому, що в цьому рядку немає нічого поганого.
Бреден Кращий

15

Див . Порівняння операторів лиття C ++ .

Однак використання одного і того ж синтаксису для різних операцій кастингу може зробити наміри програміста незрозумілими.

Крім того, у великій кодовій базі може бути важко знайти конкретний тип акторів.

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


14
struct A {};
struct B : A {};
struct C {}; 

int main()
{
    A* a = new A;    

    int i = 10;

    a = (A*) (&i); // NO ERROR! FAIL!

    //a = static_cast<A*>(&i); ERROR! SMART!

    A* b = new B;

    B* b2 = static_cast<B*>(b); // NO ERROR! SMART!

    C* c = (C*)(b); // NO ERROR! FAIL!

    //C* c = static_cast<C*>(b); ERROR! SMART!
}

5
Чи можете ви детальніше розглянути свою відповідь, додавши трохи більше опису про рішення, яке ви надаєте?
абарізон

1
Я думаю, що відповідь показує, що "static_casts" перевіряє конверсії типів, щоб переконатися, що вони проходять дійсні шляхи в графіку ієрархії. У цьому конкретному прикладі введення від A * до B * або B * до A * дозволено, оскільки A і B утворюють шлях в ієрархічному графіку. C * не на шляху, тому static_cast призведе до помилки під час компіляції. Сторінка: Можливо, варто відзначити, що передача від A * до B * може призвести до NULL з динамічним_кастом під час виконання, залежно від справжнього основного об'єкта.
Томмі Чен

7

Чудовий пост, в якому пояснюються різні ролі в C / C ++ та те, що насправді ролях у стилі C: https://anteru.net/blog/2007/12/18/200/index.html

Кастинг C-Style, використовуючи синтаксис змінної (type). Найгірше, що коли-небудь винайдено. У такому порядку це намагається зробити наступні касти: (див. Також C ++ Standard, 5.4 expr.cast, пункт 5)

  1. const_cast
  2. static_cast
  3. static_cast, а потім const_cast
  4. reinterpret_cast
  5. повторно тлумачити_наведено далі const_cast

5

static_castперевіряє під час компіляції, що конверсія не знаходиться між очевидно несумісними типами. Навпаки dynamic_cast, не перевіряється сумісність типів під час виконання. Також static_castконверсія не обов'язково є безпечною.

static_cast використовується для перетворення від покажчика до базового класу до вказівника на похідний клас або між нативними типами, наприклад, enum to int або float to int.

Користувач static_castповинен переконатися, що конверсія є безпечною.

Артикул у стилі C не виконує жодної перевірки ні під час компіляції, ні під час виконання.


3

Оскільки існує багато різних видів кастингу з різною семантикою, static_cast <> дозволяє сказати "Я роблю легальне перетворення з одного типу в інший", як з int в double. Звичайний акторський склад може означати багато речей. Ви кастинг вгору / вниз? Ви переосмислюєте вказівник?

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