Каковы некоторые примеры использования динамического приведения? - PullRequest
23 голосов
/ 26 августа 2008

Мы часто слышим / читаем, что следует избегать динамического приведения. Мне было интересно, каковы, по-вашему, примеры «полезного использования»?

Edit:

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

Ответы [ 6 ]

9 голосов
/ 19 ноября 2008

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

Итератор вектора не разыменовывается

1 голос
/ 22 сентября 2008

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

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

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

Где ContainerInterface содержит базовые полезные вещи, но это все. Если я хочу конкретный алгоритм для векторов целых чисел, не подвергая мою реализацию шаблона, полезно принять объекты интерфейса и динамически передать его 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, который был бы полиморфно разрешен, это был бы более приятный метод ООП, но я иногда предпочитаю делать это так Когда у вас есть простые контейнеры, множество алгоритмов и вы хотите скрыть свою реализацию, dynamic_cast предлагает простое и безобразное решение.

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

НТН

0 голосов
/ 29 марта 2014

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

0 голосов
/ 19 ноября 2008

Ну, было бы неплохо с методами расширения в 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;
}

было бы замечательно.

0 голосов
/ 19 сентября 2008

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

0 голосов
/ 26 августа 2008

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

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

...