Скачать MetaTrader 5

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

Авторизуйтесь или зарегистрируйтесь, чтобы добавить комментарий
whroeder1
14785
whroeder1  
В переводе с 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)

Комбинатор
16032
Комбинатор  

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

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

______

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

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

Vadim Zhunko
5226
Vadim Zhunko  
TheXpert:

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

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

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

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

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

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