C ++ строго ориентирован на производительность.Таким образом, до тех пор, пока есть некоторый сценарий использования, который позволит вам повысить производительность, C ++ позволит вам это сделать.Рассмотрим std::vector
: Конечно, есть безопасный доступ к элементу через функцию at
, которая выполняет проверку диапазона для вас.Но если вы знаете, что ваши индексы находятся в диапазоне (например, в цикле for), то эти проверки диапазона просто мертвый вес.Таким образом, вы дополнительно получаете (менее безопасный) operator[]
, который просто пропускает эти проверки.
Аналогично, если у вас есть указатель типа Base
, он может в действительности указывать на объект типа Derived
.Если вы сомневаетесь, вы бы dynamic_cast
с Base*
до Derived*
.Но это идет с некоторыми накладными расходами.Но если вы точно знаете (каким-либо образом ...), что такое подкласс на самом деле, на 100%, захотите ли вы этого?Поскольку существует естественный (даже неявный!) Путь от Derived*
до Base*
, мы хотим получить недорогой путь назад.
С другой стороны, между указателями такого естественного приведения нет.совершенно не связанных типов (таких как char
и int
или два несвязанных класса) и, таким образом, такого недорогого пути назад нет (по сравнению с dynamic_cast
, который, конечно же, недоступен).Единственный способ преобразования между ними - это reinterpret_cast
.
На самом деле reinterpret_cast также бесплатен, он просто интерпретирует указатель как другой тип со всеми рисками!И reinterpret_cast
даже может потерпеть неудачу, если вместо этого потребовался бы static_cast
(правильно, чтобы не задавать вопрос «почему бы просто не всегда использовать ...»):
class A { int a; };
class B { };
class C : public A, public B { };
B* b = new C();
C* c = reinterpret_cast<C*>(b); // FAILING!!!
С точки зрения памятимакет, C
выглядит так (даже если он скрыт от вас):
class C
{
A baseA;
B baseB; // this is what pointer b will point to!
};
Очевидно, мы получим смещение при приведении между C*
и B*
(в любом направлении), чтосчитается как static_cast
и dynamic_cast
, но не reinterpret_cast
...