Обычное приведение против static_cast против dynamic_cast [duplicate]

Поскольку strtotime требует определенного формата ввода, можно использовать DateTime :: createFromFormat (требуется php 5.3+)

// set timezone to user timezone
date_default_timezone_set($str_user_timezone);

// create date object using any given format
$date = DateTime::createFromFormat($str_user_dateformat, $str_user_datetime);

// convert given datetime to safe format for strtotime
$str_user_datetime = $date->format('Y-m-d H:i:s');

// convert to UTC
$str_UTC_datetime = gmdate($str_server_dateformat, strtotime($str_user_datetime));

// return timezone to server default
date_default_timezone_set($str_server_timezone);

1616
задан R. Martinho Fernandes 15 May 2014 в 15:15
поделиться

6 ответов

static_cast

static_cast используется для случаев, когда вы в основном хотите отменить неявное преобразование с некоторыми ограничениями и дополнениями. static_cast не выполняет проверки времени выполнения. Это следует использовать, если вы знаете, что ссылаетесь на объект определенного типа, и поэтому в проверке нет необходимости. Пример:

void func(void *data) {
  // Conversion from MyClass* -> void* is implicit
  MyClass *c = static_cast<MyClass*>(data);
  ...
}

int main() {
  MyClass c;
  start_thread(&func, &c)  // func(&c) will be called
      .join();
}

В этом примере вы знаете, что передали объект MyClass , и поэтому нет необходимости в проверке времени выполнения, чтобы убедиться в этом.

dynamic_cast

dynamic_cast ] полезен, когда вы не знаете, какой у объекта динамический тип. Он возвращает нулевой указатель, если упомянутый объект не содержит тип, приведенный к базовому классу (при приведении к ссылке в этом случае выдается исключение bad_cast ).

if (JumpStm *j = dynamic_cast<JumpStm*>(&stm)) {
  ...
} else if (ExprStm *e = dynamic_cast<ExprStm*>(&stm)) {
  ...
}

Вы не можете использовать dynamic_cast , если вы выполняете понижающее преобразование (приведение к производному классу), а тип аргумента не является полиморфным. Например, следующий код недействителен, потому что Base не содержит никаких виртуальных функций:

struct Base { };
struct Derived : Base { };
int main() {
  Derived d; Base *b = &d;
  dynamic_cast<Derived*>(b); // Invalid
}

«up-cast» (приведение к базовому классу) всегда допустимо с обоими static_cast и dynamic_cast , а также без какого-либо преобразования, поскольку «up-cast» является неявным преобразованием.

Regular Cast

Эти преобразования также называются приведением в стиле C. Приведение в стиле C в основном идентично проверке ряда последовательностей приведений C ++ и взятию первого работающего приведения C ++, без учета dynamic_cast . Излишне говорить, что это намного мощнее, так как объединяет все const_cast , static_cast и reinterpret_cast , но это также небезопасно, потому что не использует dynamic_cast .

Кроме того, приведение типов в стиле C позволяет не только выполнять это, но они также позволяют безопасно выполнять приведение к частному базовому классу, в то время как "эквивалентная" последовательность static_cast даст вам ошибку времени компиляции для этого.

Некоторые люди предпочитают стиль C. слепки из-за их краткости. Я использую их только для числовых преобразований и использую соответствующие преобразования C ++, когда задействованы определенные пользователем типы, поскольку они обеспечивают более строгую проверку.

но они также позволяют безопасно выполнять приведение к частному базовому классу, в то время как «эквивалентная» последовательность static_cast даст вам ошибку времени компиляции для этого.

Некоторые люди предпочитают приведение типов в стиле C, потому что их краткости. Я использую их только для числовых преобразований и использую соответствующие преобразования C ++, когда задействованы определенные пользователем типы, поскольку они обеспечивают более строгую проверку.

но они также позволяют безопасно выполнять приведение к частному базовому классу, в то время как «эквивалентная» последовательность static_cast даст вам ошибку времени компиляции для этого.

Некоторые люди предпочитают приведение типов в стиле C, потому что их краткости. Я использую их только для числовых преобразований и использую соответствующие преобразования C ++, когда задействованы определенные пользователем типы, поскольку они обеспечивают более строгую проверку.

1543
ответ дан 22 November 2019 в 20:09
поделиться

Необходимо посмотреть на Программирование на C++ статьи / Преобразование типа .

Это содержит хорошее описание всех различных типов броска. Следующее взято из вышеупомянутой ссылки:

(выражение) const_cast

const_cast const_cast<> () используется для добавления/удаления константы (мыс) (или энергозависимый) переменной.

(выражение) static_cast

static_cast static_cast<> () используется для кастинга между целыми типами. 'например', символ-> долго, интервал-> короткий и т.д.

Статический бросок также используется для кастинга указателей на связанные типы, например, бросая пусто* к соответствующему типу.

dynamic_cast

Динамический бросок используется для преобразования указателей и ссылок во времени выполнения, обычно в целях выбрасывания указателя или ссылки или вниз цепочки наследования (иерархия наследования).

dynamic_cast (выражение)

целевой тип должен быть типом указателя или ссылочным типом, и выражение должно оценить к указателю или ссылке. Динамические работы броска только, когда тип объекта, к которому относится выражение, совместим с целевым типом и базовым классом, имеют по крайней мере одну виртуальную функцию членства. В противном случае и тип бросаемого выражения является указателем, ПУСТОЙ УКАЗАТЕЛЬ возвращается, если динамический состав исполнителей на ссылке перестал работать, bad_cast исключение выдается. Когда это не перестало работать, динамический состав исполнителей возвращает указатель или ссылку целевого типа к объекту к который отнесенное выражение.

reinterpret_cast

Дает иное толкование броску, просто бросает один тип поразрядно другому. Любой тип указателя или целочисленный тип могут быть литыми любому другому с, дают иное толкование броску, легко допуская неправильное употребление. Например, с дают иное толкование, бросает, можно было бы, небезопасно, бросить целочисленный указатель на указатель строки.

78
ответ дан HardcoreBro 15 May 2014 в 15:15
поделиться

Избегайте использования бросков C-стиля.

броски C-стиля являются соединением константы и дают иное толкование броску, и трудно найти и заменить в Вашем коде. Программист приложения C++ должен избежать броска C-стиля.

27
ответ дан Peter Mortensen 15 May 2014 в 15:15
поделиться

dynamic_cast имеет проверку типа выполнения и только работает со ссылками и указателями, тогда как static_cast не предлагает проверку типа выполнения. Для полной информации см. статью MSDN static_cast Оператор .

11
ответ дан Peter Mortensen 15 May 2014 в 15:15
поделиться

К вашему сведению я полагаю, что Bjarne Stroustrup заключается в кавычки, что бросков C-стиля нужно избежать и что необходимо использовать static_cast или dynamic_cast если вообще возможный.

FAQ

стиля C++ Barne Stroustrup Слушает тот совет для того, что Вы будете. Я далек от того, чтобы быть гуру C++.

27
ответ дан Atul Kumar 15 May 2014 в 15:15
поделиться

Броски C-стиля соединяют const_cast, static_cast, и reinterpret_cast.

мне жаль, что C++ не имел бросков C-стиля. Броски C++ выделяются правильно (как они должны; броски обычно показательны из выполнения чего-то плохо), и правильно различайте различные виды преобразования, которое выполняют броски. Они также разрешают подобно выглядящим функциям быть записанными, например, повышение:: lexical_cast, который довольно хорош с точки зрения непротиворечивости.

15
ответ дан DrPizza 15 May 2014 в 15:15
поделиться
Другие вопросы по тегам:

Похожие вопросы: