Основным преимуществом приведений в стиле C ++ является, как вы уже сказали, безопасность типов.Каждое приведение в C ++ обрабатывает один конкретный вид преобразования (или семейство связанных преобразований), и поэтому компилятор может пойти и проверить, что вы случайно не делаете больше преобразований, которые вы намеревались, или последовательность преобразований, которая в принципе небезопасна.
Одна вещь, о которой следует подумать, это то, что, хотя это здорово, что вы чувствуете себя комфортно, используя приведения в стиле C, и, хотя это здорово, что вы не допустили ошибок с ними, другие люди, работающие с базой кода, могутне будь таким легким с этими бросками, как ты.Использование операторов приведения делает код более самодокументированным.Если у вас где-то есть приведение в стиле C, кто-то другой, читающий код, может не сразу определить, что вы делаете.Если они увидят что-то вроде
T* ptr = (T*) var;
Они могут не сразу определить, является ли это
- приведением из базового класса к производному классу или наоборот.
- Приведение к полосе
const
Отключение от var
- Приведение из целочисленного типа к указателю.
Хотя они, вероятно, могут подобрать этоИсходя из контекста, становится гораздо более очевидным, что происходит, если вы используете приведение типа
T* ptr = static_cast<T*>(var);
или
T* ptr = const_cast<T*>(var);
Еще одна причина, по которой операторы в стиле C ++ предпочитают, заключается в том, что они делаюткод более устойчив к изменениям.Например, предположим, у меня есть эта функция:
void DoSomething(Base* ptr) {
Derived* derived = (Derived *) ptr;
DoSomethingElse(derived);
}
Теперь предположим, что я понимаю, что эта функция не должна вносить какие-либо изменения в свой аргумент, поэтому я решил пометить ее const
.Например:
void DoSomething(const Base* ptr) {
Derived* derived = (Derived *) ptr;
DoSomethingElse(derived);
}
Но теперь у нас есть проблема - мой бросок в стиле C, который раньше был просто понижен, теперь также удаляет const
ness.Это может привести к простой ошибке, когда DoSomethingElse
изменяет указатель, который я передаю, хотя сам метод DoSomething
обещает этого не делать.Если вместо этого я написал этот код как
void DoSomething(Base* ptr) {
Derived* derived = static_cast<Derived *>(ptr);
DoSomethingElse(derived);
}
, а затем изменил код, добавив const
:
void DoSomething(const Base* ptr) {
Derived* derived = static_cast<Derived *>(ptr);
DoSomethingElse(derived);
}
Теперь я получу ошибку компилятора, сообщающую, что мой старый приведениене работает, что может привести меня к обнаружению логической ошибки в коде (а именно, что DoSomethingElse
изменяет свой аргумент, поэтому я не могу наивно сделать ptr
указателем на const
.
Короче говоря, использование операторов приведения в C ++ делает код более читабельным и более легким в обслуживании. Это делает логику кода более явной. И делает код менее подверженным ошибкам, так как компилятор перехватывает ошибки, как и вы.Вы делаете их или позже, когда вернетесь и измените старый код. Я бы порекомендовал в будущем попытаться использовать операторы приведения в стиле C ++ по этим основным причинам.
Что касается того, стоит ли вам возвращаться и пытатьсязаменить ваши текущие приведения в стиле C на приведения в стиле C ++, это действительно ваше дело. В качестве упражнения я бы предложил сделать это просто для того, чтобы попрактиковаться в изучении того, какие типы приведения вы используете.вы можете найти там логическую ошибку, которая сделает поиск стоящим вашего времени!