Сведения о вопросе

Mathprofi

15:32, 26th August, 2020

Теги

c++   casting   rtti   dynamic-cast    

Каковы некоторые примеры 'good use' динамического кастинга?

Просмотров: 381   Ответов: 6

Мы часто слышим / читаем, что следует избегать динамического кастинга. Мне было интересно, каков будет 'good use' примеров этого, по вашему мнению?

Редактировать:

Да, я знаю об этой другой теме : действительно, читая один из первых ответов там, я задал свой вопрос!



  Сведения об ответе

lats

01:27, 11th August, 2020

Этот недавний поток дает пример того, где он может пригодиться. Существует базовый класс Shape и производные от него классы Circle и Rectangle. При проверке на равенство очевидно, что круг не может быть равен прямоугольнику, и было бы катастрофой пытаться сравнить их. При итерации по коллекции указателей на фигуры dynamic_cast выполняет двойную функцию, сообщая вам, сопоставимы ли фигуры,и давая вам соответствующие объекты для сравнения.

Вектор итератор не уникальным


  Сведения об ответе

SILA

01:02, 5th August, 2020

Вот что я часто делаю, это не очень красиво, но это просто и полезно.

Я часто работаю с контейнерами шаблонов, которые реализуют интерфейс, представьте себе что-то вроде

template<class T>
class MyVector : public ContainerInterface
...

Где ContainerInterface имеет основные полезные вещи, но это все. Если мне нужен конкретный алгоритм на векторах целых чисел без раскрытия моей реализации шаблона, полезно принять объекты интерфейса и dynamic_cast его вниз до MyVector в реализации. Пример:

// function prototype (public API, in the header file)
void ProcessVector( ContainerInterface& vecIfce );

// function implementation (private, in the .cpp file)
void ProcessVector( ContainerInterface& vecIfce)
{
    MyVector<int>& vecInt = dynamic_cast<MyVector<int> >(vecIfce); 
    // the cast throws bad_cast in case of error but you could use a
    // more complex method to choose which low-level implementation
    // to use, basically rolling by hand your own polymorphism.

    // Process a vector of integers
    ...
}

Я мог бы добавить метод Process() к ContainerInterface, который был бы полиморфно разрешен, это был бы более приятный метод OOP, но иногда я предпочитаю делать это таким образом. Когда у вас есть простые контейнеры, много алгоритмов, и вы хотите сохранить свою реализацию скрытой, dynamic_cast предлагает простое и уродливое решение.

Вы также можете посмотреть на методы двойной отправки.

HTH


  Сведения об ответе

SEEYOU

20:28, 17th August, 2020

Мой текущий игрушечный проект использует dynamic_cast дважды: один раз, чтобы обойти отсутствие множественной отправки в C++ (это система в стиле посетителя, которая может использовать множественную отправку вместо dynamic_casts), и один раз, чтобы сделать особый случай для конкретного подтипа.

На мой взгляд, и то и другое вполне приемлемо, хотя первое, по крайней мере, проистекает из языкового дефицита. Я думаю, что это может быть обычной ситуацией, на самом деле; большинство dynamic_casts (и очень много "design patterns" в целом) являются обходными путями для конкретных языковых недостатков, а не тем, к чему стремятся.


  Сведения об ответе

dump

19:56, 5th August, 2020

Он может быть использован для обеспечения безопасности типа во время выполнения при предоставлении дескрипторов объектам через интерфейс C. Пусть все открытые классы наследуются от общего базового класса. Принимая дескриптор функции, сначала приведите его к базовому классу, а затем динамическое приведение к ожидаемому классу. Если они прошли в несенсорном дескрипторе, вы получите исключение, когда время выполнения не может найти rtti. Если они передали допустимый дескриптор неправильного типа, вы получаете указатель NULL и можете создать свое собственное исключение. Если они прошли в правильном указателе, вы хорошо идете. Это не защита от дураков,но, безусловно, лучше ловить ошибочные вызовы библиотек, чем прямое переинтерпретирование из дескриптора и ждать, пока некоторые данные не будут таинственно повреждены, когда вы передадите неправильный дескриптор.


  Сведения об ответе

#hash

11:55, 19th August, 2020

Ну это было бы действительно хорошо с методами расширения в C#.

Например, предположим, что у меня есть список объектов, и я хочу получить от них Список всех идентификаторов. Я могу пройти через них все и вытащить их, но я хотел бы сегментировать этот код для повторного использования.

так что что-то вроде

List<myObject> myObjectList = getMyObjects();

List<string> ids = myObjectList.PropertyList("id");

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

Так

public static List<string> PropertyList(this object objList, string propName) {
    var genList = (objList.GetType())objList;
}

это было бы потрясающе.


  Сведения об ответе

darknet

19:31, 21st August, 2020

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


Ответить на вопрос

Чтобы ответить на вопрос вам нужно войти в систему или зарегистрироваться