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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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



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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

Затем ptr в функцию можно передать cxx постоянную переменную, используя type-casting приведение 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