static_cast
первый бросок, который необходимо попытаться использовать. Это делает вещи как неявные преобразования между типами (такой как int
к float
, или указатель на void*
), и это может также назвать явные функции преобразования (или неявные). Во многих случаях явно утверждение static_cast
не необходимо, но важно отметить, что T(something)
синтаксис эквивалентен (T)something
и должен избежаться (больше на этом позже). T(something, something_else)
безопасно, однако, и гарантируемый вызвать конструктора.
static_cast
может также бросить через иерархии наследования. Это является ненужным при кастинге вверх (к базовому классу), но когда кастинг вниз его может использоваться, пока это не бросает до virtual
наследование. Это не делает проверки, однако, и это - неопределенное поведение к [1 110] вниз иерархия к типу, который не является на самом деле типом объекта.
const_cast
может использоваться, чтобы удалить или добавить const
к переменной; никакой другой бросок C++ не способен к удалению его (даже reinterpret_cast
). Важно отметить, что, изменяя раньше const
значение только не определено, если исходная переменная const
; если Вы используете его для взятия const
от ссылки на что-то, что не было объявлено с [1 117], это безопасно. Это может быть полезно при перегрузке функций членства на основе [1 118], например. Это может также использоваться для добавления const
к объекту, например, для вызова перегрузки функции членства.
const_cast
также работы так же над [1 121], хотя это менее распространено.
dynamic_cast
исключительно используется для обработки полиморфизма. Можно бросить указатель, или ссылка на любой полиморфный тип к любому другому типу класса (полиморфный тип имеет по крайней мере одну виртуальную функцию, объявленную или наследованную). Можно использовать его для больше, чем просто кастинга вниз †“, можно бросить боком или сгладить другую цепочку. Эти dynamic_cast
будет искать требуемый объект и возвращать его, если это возможно. Если это не может, это возвратиться nullptr
в случае указателя или броска std::bad_cast
в случае ссылки.
dynamic_cast
имеет некоторые ограничения, все же. Это не работает, если существует несколько объектов того же типа в иерархии наследования (так называемый 'страшный ромб'), и Вы не используете virtual
наследование. Это также может только пройти общедоступное наследование - это всегда не переместится до [1 128] или private
наследование. Это редко - проблема, однако, формы как таковые наследования редки.
reinterpret_cast
самый опасный бросок и должен использоваться очень экономно. Это поворачивает один тип непосредственно в другой —, такой как кастинг значения от одного указателя до другого или хранения указателя в int
, или все виды других противных вещей. В основном единственная гарантия, которую Вы получаете с [1 132], - то, что обычно при кастинге результата назад к исходному типу Вы получите то же самое значение (но не , если промежуточный тип будет меньшим, чем исходный тип). Существует много преобразований, которые reinterpret_cast
не могут сделать, также. Это используется, прежде всего, для особенно странных преобразований и побитовых обработок, как превращение потока необработанных данных в фактические данные или хранить данные в младших битах указателя на выровненные данные.
C-стиль бросил и , функциональный стиль бросил , броски, использующие (type)object
или type(object)
, соответственно, и функционально эквивалентны. Они определяются как первое из следующего, которое успешно выполняется:
const_cast
static_cast
(хотя игнорируя ограничения доступа) static_cast
(см. выше), тогда const_cast
reinterpret_cast
reinterpret_cast
, тогда const_cast
Это может поэтому использоваться в качестве замены для других бросков в некоторых случаях, но может быть чрезвычайно опасно из-за способности опуститься до reinterpret_cast
, и последний должен быть предпочтен, когда явный кастинг необходим, если Вы не уверены static_cast
, успешно выполнится, или reinterpret_cast
перестанет работать. Даже тогда рассмотрите дольше, более явная опция.
броски C-стиля также игнорируют управление доступом при выполнении static_cast
, что означает, что у них есть способность выполнить операцию, что никакой другой бросок не может. Это - главным образом клудж, тем не менее, и в моем уме просто другая причина избежать бросков C-стиля.
Я думаю, здесь есть пара проблем. Во-первых, кавычки имеют символическое значение как в PowerShell, так и в Perl. Кавычки и экранирование работают в PowerShell несколько иначе, чем в оболочке UNIX. Посмотрите man about_quoting в PowerShell.
Вторая проблема заключается в том, что командная строка perl ведет себя по-другому в Windows период. Любые двойные кавычки внутри командной строки, которые вы хотите передать в perl, должны быть экранированы в терминах perl как \ ". Это не относится к PowerShell. Так Perl работает в Windows. Обычно у вас будут аналогичные проблемы с cmd.exe.
Эти версии должны работать:
PS> & perl -e "print \`"hello, world\n\`""
hello, world
PS> $s = "print \`"hello, world\n\`""
PS> echo $s
print \"hello, world\n\"
PS> & perl -e $s
hello, world
Вы можете сделать то же самое с меньшим экранированием, используя одинарные кавычки.
PS> & perl -e 'print \"hello, world\n\"'
hello, world
PS> $s = 'print \"hello, world\n\"'
PS> echo $s
print \"hello, world\n\"
PS> & perl -e $s
hello, world
Вы также можете поместить новую строку в PowerShell вместо передачи escape-последовательности новой строки в perl для анализа .
PS> & perl -e "print \`"hello, world`n\`""
hello, world
PS> $s = "print \`"hello, world`n\`""
PS> echo $s
print \"hello, world
\"
PS> & perl -e $s
hello, world
Интересно. Кажется, что когда вы покидаете мир PowerShell, он преобразует одинарную кавычку в двойную кавычку, чтобы ее правильно интерпретировала командная оболочка Windows. (Или что-то подобное). Чтобы продемонстрировать с помощью python (который, похоже, демонстрирует ту же проблему):
PS C:\> python -c 'print "Hi from python"'
Traceback (most recent call last):
File "<string>", line 1, in <module>
NameError: name 'Hi' is not defined
это та же ошибка, которую я получаю, если пытаюсь сделать что-то подобное из командной оболочки Windows:
C:\>python -c "print "Hi from python""
Traceback (most recent call last):
File "<string>", line 1, in <module>
NameError: name 'Hi' is not defined
Как будто powershell делает это при выполнении команда:
PS C:\> $s = 'python -c "print "Hi from python""'
PS C:\> cmd /c $s
Traceback (most recent call last):
File "<string>", line 1, in <module>
NameError: name 'Hi' is not defined
Что произойдет, если вы запустите «неправильную» команду в cmd.exe вместо PowerShell? Я спрашиваю, потому что escape-последовательность, которая работает ( \ "
), принадлежит Perl; в PowerShell она будет" "".