Главная причина состоит в том, что классические броски C не делают различия между тем, что мы называем static_cast<>()
, reinterpret_cast<>()
, const_cast<>()
, и dynamic_cast<>()
. Эти четыре вещи полностью отличаются.
А static_cast<>()
обычно безопасен. Существует допустимое преобразование на языке или соответствующий конструктор, который позволяет. Единственное время это немного опасно, - когда Вы разрушаете к наследованному классу; необходимо удостовериться, что объект является на самом деле потомком, что Вы утверждаете, что это средствами, внешними на язык (как флаг в объекте). dynamic_cast<>()
безопасно, пока результат проверяется (указатель), или возможное исключение принято во внимание (ссылка).
А reinterpret_cast<>()
(или const_cast<>()
), с другой стороны, всегда опасен. Вы говорите компилятор: "доверяйте мне: Я знаю, что это не похоже foo
(это смотрит, как будто это не изменяемо), но это".
первая проблема состоит в том, что почти невозможно сказать, какой произойдет в броске C-стиля, не смотря на большие и рассеянные части кода и зная все правила.
Позволяют нам принять их:
class CDerivedClass : public CMyBase {...};
class CMyOtherStuff {...} ;
CMyBase *pSomething; // filled somewhere
Теперь, эти два компилируются тот же путь:
CDerivedClass *pMyObject;
pMyObject = static_cast<CDerivedClass*>(pSomething); // Safe; as long as we checked
pMyObject = (CDerivedClass*)(pSomething); // Same as static_cast<>
// Safe; as long as we checked
// but harder to read
Однако позволяют нам видеть этот почти идентичный код:
CMyOtherStuff *pOther;
pOther = static_cast<CMyOtherStuff*>(pSomething); // Compiler error: Can't convert
pOther = (CMyOtherStuff*)(pSomething); // No compiler error.
// Same as reinterpret_cast<>
// and it's wrong!!!
, Как Вы видите, нет никакого простого способа различать эти две ситуации, не зная много обо всех включенных классах.
вторая проблема состоит в том, что броски C-стиля слишком трудны для определения местоположения. В сложных выражениях может быть очень трудно видеть броски C-стиля. Фактически невозможно записать автоматизированный инструмент, который должен определить местоположение бросков C-стиля (например, средство поиска) без полноценного фронтенда компилятора C++. С другой стороны, легко искать "static_cast<"; или "reinterpret_cast<";.
pOther = reinterpret_cast<CMyOtherStuff*>(pSomething);
// No compiler error.
// but the presence of a reinterpret_cast<> is
// like a Siren with Red Flashing Lights in your code.
// The mere typing of it should cause you to feel VERY uncomfortable.
, Который означает, что, мало того, что броски C-стиля более опасны, но и намного более трудно найти, что они все удостоверяются, что они корректны.
Этот может быть быстрее, чем использование SUB2IND:
[r,c] = size(M); % Get the size of M
vals = M(I+r.*(J-1)); % Compute a linear index with vector operations