Что я пропустил? Приведение типов указателей базовых классов к указателям производных классов - страница 2

 
TheXpert:

Ого, таки можно.

Тогда как-то так:

Да вот не взлетает... Да даже если и взлетит - смысла в этом большого нет, так как мы для каждого производного класса должны создать переменную...
Документация по MQL5: Основы языка / Объектно-ориентированное программирование / Наследование
Документация по MQL5: Основы языка / Объектно-ориентированное программирование / Наследование
  • www.mql5.com
Основы языка / Объектно-ориентированное программирование / Наследование - Документация по MQL5
 
AlexSTAL:

Код:


Как мне получить доступ к X.Value?

попробуйте так

((CPatternWW *)X).Value = 3;


 
mql5:

попробуйте так

((CPatternWW *)X).Value = 3;


Ничего себе... у меня мозг вскипел....

Ладно, это работает, а как эту заставить работать?

class CPattern
  {
protected:
public:
   virtual void SetValue(char Val){};
  };

class CPatternWW: public CPattern
  {
protected:
public:
   int Value;
   virtual void SetValue(int Val){Value = Val;};
   void PrintValue(){Print(Value);}
  };

void OnStart()
  {
   CPattern *X;                     // В последующем Массив, где будут содержаться разные классы
   X = new CPatternWW;              // Создаём класс, отличный от базового
   
   //Эта конструкция работает:
   ((CPatternWW *)X).Value = 3;
   ((CPatternWW *)X).PrintValue();  // Выводит на печать 3
   
   // А как эту заставить работать?
   ((CPatternWW *)X).SetValue(11);
   X.SetValue(11);
   ((CPatternWW *)X).PrintValue();  // Выводит на печать всю туже 3
   
   delete X;
  }
 

Сам себе отвечаю:

((CPatternWW *)X).SetValue((int)11);

 
AlexSTAL:

Сам себе отвечаю:


Здесь имеет место ошибка в компиляторе, он должен был Вам сообщить о невозможности подобрать вызов из двух SetValue, это я исправлю.

В Вашем коде, скорее всего, неправильно используется virtual. Фактически у Вас две виртуальные функции SetValue, одна с параметром char, другая int.

Документация по MQL5: Основы языка / Объектно-ориентированное программирование / Виртуальные функции
Документация по MQL5: Основы языка / Объектно-ориентированное программирование / Виртуальные функции
  • www.mql5.com
Основы языка / Объектно-ориентированное программирование / Виртуальные функции - Документация по MQL5
 
mql5:

Здесь имеет место ошибка в компиляторе, он должен был Вам сообщить о невозможности подобрать вызов из двух SetValue, это я исправлю.

В Вашем коде, скорее всего, неправильно используется virtual. Фактически у Вас две виртуальные функции SetValue, одна с параметром char, другая int.

Так он вроде бы правильно подбирает...

Как в итоге то правильно? Именно для моей конструкции

 

Я бы сделал так.

class CPattern
  {
protected:
public:
   virtual void SetValue(int Val) { }
   virtual void PrintValue() { }

  };

class CPatternWW: public CPattern
  {
protected:
public:
   int Value;
   virtual void SetValue(int Val){Value = Val;};
   virtual void PrintValue(){ Print(Value); }
  };

void OnStart()
  {
   CPattern *X;                     // В последующем Массив, где будут содержаться разные классы
   X = new CPatternWW;              // Создаём класс, отличный от базового
   
   //Эта конструкция работает:
   ((CPatternWW *)X).Value = 3;
   X.PrintValue();  // Выводит на печать 3
   
   //и эта работает:
   X.SetValue(11);
   X.PrintValue();  // Выводит на печать всю туже 3
   
   delete X;
  }

 
mql5:

Я бы сделал так.

class CPattern
  {
protected:
public:
   virtual void SetValue(int Val) { }
   virtual void PrintValue() { }

  };

class CPatternWW: public CPattern
  {
protected:
public:
   int Value;
   virtual void SetValue(int Val){Value = Val;};
   virtual void PrintValue(){ Print(Value); }
  };

void OnStart()
  {
   CPattern *X;                     // В последующем Массив, где будут содержаться разные классы
   X = new CPatternWW;              // Создаём класс, отличный от базового
   
   //Эта конструкция работает:
   ((CPatternWW *)X).Value = 3;
   X.PrintValue();  // Выводит на печать 3
   
   //и эта работает:
   X.SetValue(11);
   X.PrintValue();  // Выводит на печать всю туже 3
   
   delete X;
  }

Не! Ну это понятно! Только вся и соль в том, что тип переменной Value в каждом производном классе (а их будет штук 30 к примеру) будет разный (структура). Все объекты будут содержаться в одном массиве...

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

Вопрос то возник из-за того, что у Вас в документации я нигде не нашёл вышенаписанной конструкции с множеством скобочек для приведения типа....

 
AlexSTAL:

Не! Ну это понятно! Только вся и соль в том, что тип переменной Value в каждом производном классе (а их будет штук 30 к примеру) будет разный (структура). Все объекты будут содержаться в одном массиве...

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

Вопрос то возник из-за того, что у Вас в документации я нигде не нашёл вышенаписанной конструкции с множеством скобочек для приведения типа....

Запись
((Type*)x).Func();
равносильна
Type *Y=X;
Y.Func();


Рекомендую завести виртуальный метод Type() который позволит определить по базовому указателю, реальный тип  объекта.
Преобразовать базовый указатель к реальному и уже с ним работать. Некорректное преобразование указателя вызовет критическую ошибку выполнения.

 
AlexSTAL:

Не! Ну это понятно! Только вся и соль в том, что тип переменной Value в каждом производном классе (а их будет штук 30 к примеру) будет разный (структура).

что-то у Вас не так с архитектурой...
Причина обращения: