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

 
В переводе с dynamic_cast - MQL4 форум
В нижней части типажей - MQL4 Documentation он говорит
Можно использовать явное приведение типов для преобразования указателей базового класса в указатели производного класса. Но необходимо быть полностью уверенным в допустимости такого преобразования, так как в противном случае возникнет критическая ошибка времени выполнения и mql4-программа будет остановлена.
Учитывая эти классы
class base{ ... };
class derv : public base{ ...};
class other : public base{ ... };
Этот код аварий
base* obj = new other;
derv* d   = (derv*)obj; // авария
Поскольку obj является other, но other не происходит от derv
C++ код может застраховать это с помощью dynamic_cast
<type> *p_subclass = dynamic_cast<<type> *>( p_obj );
Mql4/5 не оказывать такую ​​поддержку.
Но эта возможность может быть синтезирован с простым базовым классом и макроса
class Polymorphic{
 public:
   virtual bool         isA(string c)           const{   return(FALSE); };
   virtual Polymorphic* dynamic_cast(string c)  const{   return(NULL);  };
// #define POLYMORPHIC(stringCLASS, typenameBASE)                              \
//    virtual bool isA(string c)                   const{                      \
//       return( c == stringCLASS || typenameBASE::IsA(c) ); };                \
//    virtual Polymorphic* dynamic_cast(string c)  const{                      \
//       return( isA(stringCLASS) ? GetPointer(this) : NULL ); }
};
Я разделил макрос здесь для удобства чтения. Она должна быть на одной линии в mql4/5
Учитывая эти определения
class base : public Polymorphic{
 public: POLYMORPHIC("base",Polymorphic);
   void iAM(int i){ Print("iam a base "+i); }
};
class derv : public base{
 public:  POLYMORPHIC("derv",base);
   void iAM(int i){ Print("iam a derv:base "+i); }
};
class other : public base{
 public: POLYMORPHIC("other",base);
   void iAM(int i){ Print("iam a other:base "+i); }
};
Я положил макрос рядом с открывающей скобки, поскольку имя класса (в виде строки) и базовый класс должен точно соответствовать. (Должна быть строка с Metaquotes не обеспечивают # оператор в препроцессора. Почему нет?)
Этот сценарий производит
void OnStart(){
   base* obj = new other;
   derv*  d = obj.dynamic_cast("derv"); if(d) d.iAM(__LINE__); } // 
   if(obj.isA("other")){ other* o=(other*)obj; o.iAM(__LINE__);  // iam a other:base nn
d = NULL с derv является base, но не other. До приведен к other успешно, так как obj является other. QED.

См. прикрепленный файл для большего количества примеров. (Английский сообщение dynamic_cast - MQL4 forum)

 

Извините, а в чем сакральная суть преобразования одного класса в заведомо другой?

В С++ это тоже не будет работать, и в результате работы dynamic_cast будет выдано исключение std::bad_cast

______

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

Ну да ладно. Пусть таки пользуется. Но использование заведомо небезопасного преобразования это потенциальные непредвиденные косяки, которые будут ооочень и оооочень тяжело отлавливаться.

 
TheXpert:

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

Ну да ладно. Пусть таки пользуется. Но использование заведомо небезопасного преобразования это потенциальные непредвиденные косяки, которые будут ооочень и оооочень тяжело отлавливаться.

Это точно! До сих пор не пришлось использовать. Всегда есть возможность обойтись без динамического приведения типа класса.
 
Как это должно работать? Вижу, что в каждом классе есть реализация виртуальной функции, вставляемая туда через #define. А что внутри функции происходит - непонятно.
У меня компилятор выдаёт кучу ошибок.
Этот код наверное именно то, что я ищу т. к. я хочу класс, который может хранить объекты любых типов, но на выходе вернёт указатель типа объекта который в него поместили.
Это нужно для того, что бы одной строкой кода вызвать метод класса, указатель на который хранится в списке:
arrObj.At(7)."методы класса хранимого в списке";
 

Сейчас в MQL есть встроенный dynamic_cast.

Но для Вашей задачи это не подходит.

 
Да, dynamic_cast я пытался использовать внутри класса, но, как Вы и сказали, он мне не подошёл. Неделю я уже копаюсь во всяких виртуальных функциях, указателях на функции, шаблонах функций, локальных макроподстановках, пихая всё это вместе и раздельно, и всё безрезультатно. Только сегодня додумался поместить весь класс в #define и в параметрах передавать типы данных.
Не знаю, насколько это хорошо, но работает.
Причина обращения: