Назад к вопросам
Junior
78
questionbank

Назовите операторы приведения типов в C++.

Sobes Copilot

Получайте ответы в реальном времени

Ответ от нейросети

sobes.tech AI

В C++ используются следующие операторы приведения типов:

  • static_cast: Выполняет преобразования между связанными типами, где компилятор может проверить корректность. Например, между числовыми типами, указателем на базовый класс к указателю на производный (без виртуальных функций), и наоборот, между указателями и void*. Небезопасен при преобразованиях типа Derived* к Base* если нет гарантий, что указатель действительно указывает на объект Derived.
  • dynamic_cast: Используется для безопасного приведения типа указателей и ссылок в иерархии классов с виртуальными функциями. Проверка типа выполняется во время выполнения (runtime). Если приведение невозможно, для указателей возвращается nullptr, для ссылок генерируется исключение std::bad_cast. Требует, чтобы тип имел виртуальные функции (полиморфен).
  • const_cast: Используется для изменения (удаления или добавления) квалификаторов const и volatile. Использование для снятия const с объекта, изначально объявленного как const, и его последующего изменения приводит к неопределённому поведению.
  • reinterpret_cast: Выполняет низкоуровневое, наименее безопасное преобразование. Позволяет преобразовать один тип указателя в другой, указатель в целое число, и наоборот, без какой-либо проверки. Результат зависит от реализации и может быть непереносимым. Обычно используется для взаимодействия с низкоуровневым API или оборудованием.

Пример использования:

#include <iostream>
#include <vector>

class Base {
public:
    virtual ~Base() = default; // Виртуальный деструктор для dynamic_cast
    void baseMethod() { std::cout << "Base method\n"; }
};

class Derived : public Base {
public:
    void derivedMethod() { std::cout << "Derived method\n"; }
};

int main() {
    double d = 3.14;
    int i = static_cast<int>(d); // static_cast: double к int

    Base* basePtr = new Derived();
    Derived* derivedPtr = dynamic_cast<Derived*>(basePtr); // dynamic_cast: Base* к Derived*

    if (derivedPtr) {
        derivedPtr->derivedMethod();
    } else {
        std::cout << "dynamic_cast failed\n";
    }

    const int constVal = 10;
    int* nonConstPtr = const_cast<int*>(&constVal); // const_cast: const int* к int*
    // *nonConstPtr = 20; // Неопределенное поведение, если constVal изначально объявлен с const

    unsigned long address = reinterpret_cast<unsigned long>(basePtr); // reinterpret_cast: указатель к целому числу

    std::cout << "static_cast result: " << i << std::endl;
    std::cout << "reinterpret_cast result: " << address << std::endl;

    delete basePtr;
    return 0;
}