Модераторы: Poseidon, Snowy, bems, MetalFan
  

Поиск:

Ответ в темуСоздание новой темы Создание опроса
> ООП проблемы с нужным классом, нужный конструктор\ получить нужный клас 
V
    Опции темы
relate
Дата 19.2.2010, 11:21 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Новичок



Профиль
Группа: Участник
Сообщений: 8
Регистрация: 14.12.2009

Репутация: нет
Всего: нет



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

Code simple:
Код


unit Base_
type

THpCustomfF_class_ConvertWay = class of THpCustomfF_ConvertWay;

THpCustomfF_Data =class(THpCustom_Data)
  {==== Story ==================================================================
  базовый класс данных из файла
  -----------------------------------------------------------------------------}
  protected
    ....
    {cпособ конвертирования}
    fConvertWay : THpCustomff_ConvertWay;
    {список доступных классов способов конвертирования этих данных}
    fConvertWayAvailable: array of THpCustomfF_class_ConvertWay;
    ...
  public
//    constructor Create;
    destructor  Destroy; override;
    {}
    property convertWay : THpCustomff_ConvertWay read fConvertWay;
    property convertWayAvailable[index: integer]: THpCustomfF_class_ConvertWay read CWAvailableGet;
    {установить способ конвертирования данных}
    procedure convertWaySet4it (Class_CW: THpCustomfF_class_ConvertWay);
    ...
end;


implementation

{==============================================================================}
{установить способ конвертирования данных}
procedure THpCustomfF_Data.convertWaySet4it (Class_CW: THpCustomfF_class_ConvertWay);
  begin

    if (self.fConvertWay<>nil) then
      if (self.fConvertWay.ClassName = Class_CW.ClassName)
        then exit;

    FreeAndNil(self.fConvertWay);
    self.fConvertWay := Class_CW.Create
  end;
end.



Код


unit Coord
type

THpFF_Data_CoordX =class(THpCustomfF_Data, iHp_FF, iHp_Data_CoordX)
  {==== Story ==================================================================
  класс данных координата Х
  -----------------------------------------------------------------------------}
  private
  protected
  public
    constructor Create;
  end;

implementation
{==============================================================================}
constructor THpFF_Data_CoordX.Create;
  begin
    inherited Create;
    {}
    {список доступных классов способов конвертирования этих данных}
    setLength(self.fConvertWayAvailable,3);
    self.fConvertWayAvailable[0] := THpFF_ConvertWay_CoordGMS;
    self.fConvertWayAvailable[1] := THpFF_ConvertWay_CoordMS;
    self.fConvertWayAvailable[2] := THpFF_ConvertWay_CoordS;
    {cпособ конвертирования}
    self.fConvertWay := self.fConvertWayAvailable[0].Create; <=!!! ВЫЗЫВАЕТСЯ КОНСТРУКТОР THpCustomfF_ConvertWay, а хочется конструктор THpFF_ConvertWay_CoordGMS
  end;
end.



Можно сделать self.fConvertWay := THpFF_ConvertWay_CoordGMS.create;
Но как поступить с функцией  THpCustomfF_Data.convertWaySet4it ???
Мне удобно ее пользовать d_f.convertWaySet4it(d_f.convertWayAvailable[1]); А имя класса, что храниться в массиве брать, как class funtion NameStr: string;
Да и список доступных способов преобразования fConvertWayAvailable каждый наследник THpCustomfF_Data создает свой...

Помогите pls 

    self.fConvertWayAvailable[0] := THpFF_ConvertWay_CoordGMS;
    self.fConvertWay := self.fConvertWayAvailable[0].Create; <= Как вызвать конструктор класса THpFF_ConvertWay_CoordGMS ?

PM MAIL   Вверх
CodeMonkey
Дата 19.2.2010, 14:07 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Эксперт
***


Профиль
Группа: Завсегдатай
Сообщений: 1839
Регистрация: 24.6.2008
Где: Россия, Тверь

Репутация: 38
Всего: 89



Так конструктор ведь не виртуальный. Сделайте виртуальным.


--------------------
Опытный программист на C++ легко решает любые не существующие в Паскале проблемы.
PM MAIL WWW ICQ Skype GTalk Jabber   Вверх
relate
Дата 19.2.2010, 18:12 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Новичок



Профиль
Группа: Участник
Сообщений: 8
Регистрация: 14.12.2009

Репутация: нет
Всего: нет



Хм, конструктор базового класса?
Код

{--.--.20--====================================================================}
  THpCustomfF_ConvertWay = class (TObject)
  {==== Story ==================================================================
  базовый класс cпособа конвертирования
  -----------------------------------------------------------------------------}
  protected
    {описание данных, которые берем из файла}
    fdataFF : THpCustomff_CW_DFRelated;

    {Функция для конвертирования значений из файла в данные используемые в программе}
    function ConvertF2P (DataFromFile:array of string   // Данные из файла
                        ): double;  virtual; abstract;  // Результат: данные используемые в программе
    {Функция для конвертирования значений из данных используемых в программе в данные для записи в файл}
    function ConvertP2F (DataInProg :double             // Данные используемые в программе
                        ): String1D; virtual; abstract; // Результат: данные для записи в файл
  public
    constructor Create;{сделал, не помогло} virtual;
    destructor  Destroy; override;

    {Имя способа конвертирования}
    class function name: string; virtual; abstract;
    {описание данных, которые берем из файла}
    property datff: THpCustomff_CW_DFRelated read fdataFF;
  end;



Не помогло
Убрал virtual

В потомке?

Код

{--.--.20--====================================================================}
  THpFF_ConvertWay_CoordGMS = class (THpCustomfF_ConvertWay)
  {==== Story ==================================================================
  класс cпособа конвертирования
  координата: градусы минуты секунды
  -----------------------------------------------------------------------------}
  protected
    {Функция для конвертирования значений из файла в данные используемые в программе}
    function ConvertF2P (DataFromFile:array of string   // Данные из файла
                        ): double;  override;  // Результат: данные используемые в программе
    {Функция для конвертирования значений из данных используемых в программе в данные для записи в файл}
    function ConvertP2F (DataInProg :double             // Данные используемые в программе
                        ): String1D; override; // Результат: данные для записи в файл
  public
    constructor Create; {сделал, тож не помогло} virtual;
    {Имя способа конвертирования}
    class function name: string; override;
  end;


Спасибо за совет, но...
Не помогло... вызывается конструктор THpCustomfF_ConvertWay... и все.
 Вопрос остается открытым help please  
 
PM MAIL   Вверх
relate
Дата 19.2.2010, 18:35 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Новичок



Профиль
Группа: Участник
Сообщений: 8
Регистрация: 14.12.2009

Репутация: нет
Всего: нет



По сути virtual, если не изменяет память меняет расположение метода в VMT использование virtual оправданно если метод используется часто....
PM MAIL   Вверх
relate
Дата 19.2.2010, 18:50 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Новичок



Профиль
Группа: Участник
Сообщений: 8
Регистрация: 14.12.2009

Репутация: нет
Всего: нет



О! все это натолкнуло на мысль сделать метод Create в базовом классе абстрактным:

Код

{--.--.20--====================================================================}
  THpCustomfF_ConvertWay = class (TObject)
  {==== Story ==================================================================
  базовый класс cпособа конвертирования
  -----------------------------------------------------------------------------}
  protected
    {описание данных, которые берем из файла}
    fdataFF : THpCustomff_CW_DFRelated;

    {Функция для конвертирования значений из файла в данные используемые в программе}
    function ConvertF2P (DataFromFile:array of string   // Данные из файла
                        ): double;  virtual; abstract;  // Результат: данные используемые в программе
    {Функция для конвертирования значений из данных используемых в программе в данные для записи в файл}
    function ConvertP2F (DataInProg :double             // Данные используемые в программе
                        ): String1D; virtual; abstract; // Результат: данные для записи в файл
  public
    constructor Create; virtual; abstract; {делаем метод абстрактным -отдаем реализацию его потомкам, не просто обязываем их реализовывать его ;-)}
    destructor  Destroy; override;

    {Имя способа конвертирования}
    class function name: string; virtual; abstract;
    {описание данных, которые берем из файла}
    property datff: THpCustomff_CW_DFRelated read fdataFF;
  end;


в классе потомке реализовываем его:

Код

{--.--.20--====================================================================}
  THpFF_ConvertWay_CoordGMS = class (THpCustomfF_ConvertWay)
  {==== Story ==================================================================
  класс cпособа конвертирования
  координата: градусы минуты секунды
  -----------------------------------------------------------------------------}
  protected
    {Функция для конвертирования значений из файла в данные используемые в программе}
    function ConvertF2P (DataFromFile:array of string   // Данные из файла
                        ): double;  override;  // Результат: данные используемые в программе
    {Функция для конвертирования значений из данных используемых в программе в данные для записи в файл}
    function ConvertP2F (DataInProg :double             // Данные используемые в программе
                        ): String1D; override; // Результат: данные для записи в файл
  public
    constructor Create; override; {реализовывать абстрактный метод родителя бум здесь}
    {Имя способа конвертирования}
    class function name: string; override;
  end;


и в конструкторе небольшие изменения:

Код

{==============================================================================}
constructor THpFF_ConvertWay_CoordGMS.Create;
  begin
//    inherited Create; {теперь мы не можем вызывать конструктор предка -он абстактный}
    TObject.Create; {вместо этого явно вызываем конструктор родителя 
                              TObject
                              THpCustomfF_ConvertWay   
                              THpFF_ConvertWay_CoordGMS }
    {}
    {описание данных, которые берем из файла}
    self.fdataFF:= THpFF_CW_DFRelated_CoordGMS.Create;
  end;



и о чудо! работает )))))))))))
Ура, заработало!  smile 


PM MAIL   Вверх
relate
Дата 19.2.2010, 19:24 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Новичок



Профиль
Группа: Участник
Сообщений: 8
Регистрация: 14.12.2009

Репутация: нет
Всего: нет



CodeMonkey

Спасибо за направление поиска!
Может вы, говоря
Цитата
 сделать виртуальным
 подразумевали  ввиду абстрактным  smile 
разбежались в терминогологии

Thanks 4 you!!! Реутинг не повышается -у меня менее 100 постов

Это сообщение отредактировал(а) relate - 20.2.2010, 04:58
PM MAIL   Вверх
relate
Дата 19.2.2010, 21:43 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Новичок



Профиль
Группа: Участник
Сообщений: 8
Регистрация: 14.12.2009

Репутация: нет
Всего: нет



Еще один вариант решения проблеммы.

Подсказал Gelios -админ дру сайта:

Цитата

я юзал такую схему. 
1. регистрировал классы RegisterClass 
2. FindCalss(classname).Create 


Код

procedure TAnyCollection.Added(var Item: TCollectionItem);
var
  Result: TCollectionItem;
  cl: TCollectionItemClass;
  col: TCollection;
begin
  // Создадим элемент с нужным типом.
  // Для этого используем имя класса из массива
  // В этот массив будут заносится элементы методом AddEx
  try
    cl := TCollectionItemClass(FindClass(FAnyClass[Item.Index]));
    col := Item.Collection;
    Result := cl.Create(col);
    Item.Free;
    Item := Result;
  except
    Item := nil; // в случае ошибки ничего не делаем
  end;
end;
 


обрати внимание на тип переменной cl, и какой у тебя тип для аналогичной конструкции

PM MAIL   Вверх
  
Ответ в темуСоздание новой темы Создание опроса
Правила форума "Delphi: Общие вопросы"
SnowyMetalFan
bemsPoseidon
Rrader

Запрещается!

1. Публиковать ссылки на вскрытые компоненты

2. Обсуждать взлом компонентов и делиться вскрытыми компонентами

  • Литературу по Дельфи обсуждаем здесь
  • Действия модераторов можно обсудить здесь
  • С просьбами о написании курсовой, реферата и т.п. обращаться сюда
  • Вопросы по реализации алгоритмов рассматриваются здесь
  • 90% ответов на свои вопросы можно найти в DRKB (Delphi Russian Knowledge Base) - крупнейшем в рунете сборнике материалов по Дельфи


Если Вам понравилась атмосфера форума, заходите к нам чаще! С уважением, Snowy, MetalFan, bems, Poseidon, Rrader.

 
0 Пользователей читают эту тему (0 Гостей и 0 Скрытых Пользователей)
0 Пользователей:
« Предыдущая тема | Delphi: Общие вопросы | Следующая тема »


 




[ Время генерации скрипта: 0.0490 ]   [ Использовано запросов: 22 ]   [ GZIP включён ]


Реклама на сайте     Информационное спонсорство

 
По вопросам размещения рекламы пишите на vladimir(sobaka)vingrad.ru
Отказ от ответственности     Powered by Invision Power Board(R) 1.3 © 2003  IPS, Inc.