Обычное приведение, static_cast и dynamic_cast

Статическое приведение

Статическое приведение выполняет преобразования между совместимыми типами. Он похож на приведение в стиле C, но является более ограничительным. Например, приведение в стиле C позволит целочисленному указателю указывать на char.

char c = 10;       // 1 byte
int *p = (int*)&c; // 4 bytes

Так как это приводит к 4-байтовому pointer указателю, указывающему на casting 1 байт выделенной памяти, запись cast в этот указатель либо вызовет casting ошибку времени выполнения, либо ptr перезапишет некоторую соседнюю pointers память.

*p = 5; // run-time error: stack corruption

В отличие от приведения cxx в стиле C, статическое приведение cast позволит компилятору проверить typecast совместимость типов данных ptr указателя и указателя, что cast позволяет программисту уловить type-casting это неправильное присвоение pointers указателя во время компиляции.

int *q = static_cast(&c); // compile-time error

Переосмыслить актерский состав

Чтобы type-casting принудительно преобразовать cpp указатель, так же, как приведение casting в стиле C в фоновом режиме, вместо cast этого будет использоваться type-casting приведение по-новому.

int *r = reinterpret_cast(&c); // forced conversion

Это type-casting приведение обрабатывает преобразования c++ между определенными несвязанными ptr типами, например, из одного ptr типа указателя в другой несовместимый typecast тип указателя. Он просто casting выполнит двоичную копию данных, не c++ изменяя базовый битовый шаблон. Обратите cast внимание, что результат такой casting низкоуровневой операции зависит pointer от системы и, следовательно, не pointers переносится. Его следует casting использовать с осторожностью, если typecast его нельзя полностью избежать.

Динамическое приведение

Он c++ используется только для преобразования pointer указателей на объекты и ссылок typecast на объекты в другие указатели cxx или ссылочные типы в иерархии typecast наследования. Это единственное typecast приведение, которое гарантирует, что pointers указанный объект может быть cxx преобразован, путем выполнения c++ проверки во время выполнения, ссылается cast ли указатель на полный объект c++ целевого типа. Чтобы эта pointer проверка во время выполнения pointers была возможной, объект должен pointer быть полиморфным. То есть cast класс должен определять или type-casting наследовать хотя бы одну ptr виртуальную функцию. Это cpp связано с тем, что компилятор pointer будет генерировать только cpp необходимую информацию о c++ типе времени выполнения для pointers таких объектов.

Примеры динамического приведения

В приведенном casting ниже примере указатель MyChild преобразуется casting в указатель MyBase с помощью динамического typecast преобразования. Это преобразование type-casting производного в базовое завершается type-casting успешно, поскольку дочерний cast объект включает в себя полный cast базовый объект.

class MyBase 
{ 
  public:
  virtual void test() {}
};
class MyChild : public MyBase {};



int main()
{
  MyChild *child = new MyChild();
  MyBase  *base = dynamic_cast(child); // ok
}

В следующем c++ примере предпринимается попытка pointers преобразовать указатель MyBase в type-casting указатель MyChild. Поскольку базовый typecast объект не содержит полного typecast дочернего объекта, преобразование cast указателя завершится ошибкой. Чтобы ptr указать это, динамическое ptr приведение возвращает нулевой ptr указатель. Это дает удобный pointers способ проверить, успешно pointers ли выполнено преобразование.

MyBase  *base = new MyBase();
MyChild *child = dynamic_cast(base);

 
if (child == 0) 
std::cout << "Null pointer returned";

Если cast вместо указателя преобразуется c++ ссылка, то динамическое приведение ptr завершится ошибкой, вызвав cpp исключение bad_cast. Для этого нужно c++ использовать инструкцию try-catch.

#include 
// …  
try
{ 
  MyChild &child = dynamic_cast(*base);
}
catch(std::bad_cast &e) 
{ 
  std::cout << e.what(); // bad dynamic_cast
}

Динамическое или статическое приведение

Преимущество pointers использования динамического c++ преобразования типов состоит pointer в том, что они позволяют ptr программисту проверять успешность pointers преобразования во время выполнения. Недостатком type-casting является то, что выполнение c++ этой проверки связано с дополнительными cpp расходами на производительность. По cast этой причине в первом примере casting было бы предпочтительнее ptr использовать статическое cxx приведение, потому что преобразование cast производного в базовое никогда cxx не приведет к сбою.

MyBase *base = static_cast(child); // ok

Однако c++ во втором примере преобразование casting может быть успешным или неудачным. Он pointer завершится ошибкой, если type-casting объект MyBase содержит экземпляр ptr MyBase, и будет успешным, если pointer он содержит экземпляр MyChild. В c++ некоторых ситуациях это может ptr быть неизвестно до времени pointers выполнения. В этом случае casting лучше использовать динамическое cast приведение, чем статическое.

// Succeeds for a MyChild object
MyChild *child = dynamic_cast(base);

Если cast бы преобразование базового type-casting значения в производное было type-casting выполнено с использованием cpp статического преобразования, а type-casting не динамического преобразования, преобразование ptr не завершилось бы ошибкой. Он casting вернул бы указатель, ссылающийся cpp на неполный объект. Разыменование pointer такого указателя может привести c++ к ошибкам во время выполнения.

// Allowed, but invalid
MyChild *child = static_cast(base);
 
// Incomplete MyChild object dereferenced
(*child);

Константное приведение

Он ptr в основном используется для cast добавления или удаления модификатора pointer const переменной.

const int myConst = 5;
int *nonConst = const_cast(&myConst); // removes const

Хотя приведение cpp const позволяет изменять значение cast константы, это по-прежнему c++ является недопустимым кодом, который typecast может вызвать ошибку времени typecast выполнения. Это могло произойти, например, если cast константа была расположена casting в разделе постоянной памяти.

*nonConst = 10; // potential run-time error

const приведение casting вместо этого используется pointer в основном, когда есть функция, которая cpp принимает аргумент непостоянного c++ указателя, даже если она casting не изменяет указателя.

void print(int *p) 
{
   std::cout << *p;
}

Затем cxx в функцию можно передать c++ постоянную переменную, используя pointers приведение const.

print(&myConst); // error: cannot convert 
                 // const int* to int*
 
print(nonConst); // allowed

Source and More Explanations

c++

pointers

casting

2022-11-19T05:28:19+00:00