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

Поиск:

Ответ в темуСоздание новой темы Создание опроса
> Создание объекта от TClass, Неправильное создание объекта 
V
    Опции темы
Budy
Дата 20.11.2009, 08:27 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Опытный
**


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

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



:Привествую

Есть код
Код
uses
  Dialogs;

type
  TBaseCls = class
    constructor Create;    
  end;
  
var
  b : TBaseCls;  
  p : ^TObject;
  c : TClass;

constructor TBaseCls.Create;    
begin
  ShowMessage(Self.ClassType.ClassName);
end;

begin
  c := TBaseCls;
  
  // Block A
  GetMem(p, SizeOf(TObject));
  p^ := c.Create;
  p^.Free;
  FreeMem(p);
  
  // Block B
  b := TBaseCls.Create;
  b.Free;
end.


При выполнении блока A создается объект класса TObject, при том TBaseCls.Create не выполняется, хотя указан этот класс.
Помогите плиз выбрать нужный подход.

Для блока A необходимо указать класс, от которого будет создан объект.
Я написал обрезанный пример. Строю иерархическое дерево классов, а потому в блоке A не будет известен класс TBaseCls.


--------------------
Как ты назовешь свой корабль, так на нем и напишут
user posted image
PM MAIL WWW ICQ   Вверх
cemick
Дата 20.11.2009, 10:07 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Опытный
**


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

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



 smile 

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

PM MAIL WWW   Вверх
Budy
Дата 20.11.2009, 11:13 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Опытный
**


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

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



Хочу написать класс листинга с автоматическим созданием и удалением элементов.

Код

type
TPointers : Array of Pointer;

TBaseList = class
  List : TPointers;
  ItemClass : TClass;
  constructor Create(AItemClass : TClass);
  procedure Add : TPointer;
  procedure Delete(Index : Integer);
  ...
end;

constuctor TBaseList.Create;
begin
  ItemClass := AItemClass;
end;

function TBaseList.Add;
begin
  GetMem(Result, SizeOf(TObject));
  Result^ := ItemClass.Create;
  SetLength(List, High(List)+2);
  List[High(List)] := Result;
end;


Код

var MyList : TBaseList;


Проблема в следующем. Есть класс
Код

type

TMyClass = class
  constructor Create; // стандартный метод для всех объектов, но я меняю на свой
end;

constructor TMyClass.Create;
begin
  // чего-нибудь
end;


Когда создаю MyList, я должен указать класс, от которого должны создаваться элементы списка.
MyList := TBaseList.Create(TMyClass);

Потом я создаю список, например вот так:
var o : Pointer;
o := MyList.Add;
TMyObject(o^).SampleProc;

Дак вот это самое "чего-нибудь" не происходит.


--------------------
Как ты назовешь свой корабль, так на нем и напишут
user posted image
PM MAIL WWW ICQ   Вверх
cemick
Дата 20.11.2009, 11:35 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Опытный
**


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

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



Передавать надо ссылку на класс

type TMyClassRef = class of TMyClass;
PM MAIL WWW   Вверх
Budy
Дата 20.11.2009, 11:43 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Опытный
**


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

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



Цитата(cemick @  20.11.2009,  14:35 Найти цитируемый пост)
Передавать надо ссылку на классtype TMyClassRef = class of TMyClass;

хм...


--------------------
Как ты назовешь свой корабль, так на нем и напишут
user posted image
PM MAIL WWW ICQ   Вверх
Budy
Дата 20.11.2009, 12:13 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Опытный
**


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

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



Путем усиленных колебаний мозга во всех 8ми направлениях, пришел к такому виду (см.первый код):
Код
uses
  Dialogs;

type
  PMyObject = ^TMyObject;
  TMyObject = class
    procedure Init; dynamic; abstract;
  end;

  TMyClass = class of TMyObject;

  TMyObject1 = class(TMyObject)
    // Метод инициализации
    procedure Init; override;
  end;

  TMyObject2 = class(TMyObject)
    // Нет метода инициализцаии
  end;

procedure TMyObject1.Init;    
begin
  ShowMessage('Init');
end;

var
  p : PMyObject;
  c : TMyClass;

begin
  // Block A
  c := TMyObject1;
  GetMem(p, SizeOf(TObject));
  p^ := c.Create;
  try
    p^.Init;
  except; end;
  p^.Free;
  FreeMem(p);

  // Block B
  c := TMyObject2;
  GetMem(p, SizeOf(TObject));
  p^ := c.Create;
  try
    p^.Init;
  except; end;
  p^.Free;
  FreeMem(p);
end.


Блок try..except..end; будет выдавать ошибку в случае если метод Init в объекте не описан. Как можно проверить существование метода в классе?


--------------------
Как ты назовешь свой корабль, так на нем и напишут
user posted image
PM MAIL WWW ICQ   Вверх
Budy
Дата 20.11.2009, 12:34 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Опытный
**


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

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



Разобрался самостоятельно. Всем спасибо за внимание. Если кому интересно, пришел к следующему:
Код

uses
  Dialogs;

type
  PMyObject = ^TMyObject;
  TMyObject = class
  published
    procedure Init; virtual;
  end;

  TMyClass = class of TMyObject;

  TMyObject1 = class(TMyObject)
  published
    // Метод инициализации
    procedure Init; override;
  end;

  TMyObject2 = class(TMyObject)
    // Нет метода инициализцаии
  end;

procedure TMyObject.Init;
begin
end;

procedure TMyObject1.Init;    
begin
  ShowMessage('Init');
end;

var
  p : PMyObject;
  c : TMyClass;
  m : procedure;

begin
  // Block A
  c := TMyObject1;
  GetMem(p, SizeOf(TObject));
  p^ := c.Create;
  p^.Init;
  p^.Free;
  FreeMem(p);

  // Block B
  c := TMyObject2;
  GetMem(p, SizeOf(TObject));
  p^ := c.Create;
  p^.Init;
  p^.Free;
  FreeMem(p);
end.



--------------------
Как ты назовешь свой корабль, так на нем и напишут
user posted image
PM MAIL WWW ICQ   Вверх
cemick
Дата 20.11.2009, 12:51 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Опытный
**


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

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



oh my god... 

Я бы ваш код переделал так

Код

unit Unit2;

interface
uses
  Dialogs,  SysUtils;
type

  TMyObject = class
    procedure Init; dynamic; abstract;
  end;

  TMyClass = class of TMyObject;

  TMyObject1 = class(TMyObject)
    // Метод инициализации
    procedure Init; override;
  end;

  TMyObject2 = class(TMyObject)
    // Нет метода инициализцаии
  end;

implementation

procedure TMyObject1.Init;    
begin
  ShowMessage('Init');
end;

var
  p : TMyObject;
  c : TMyClass;

begin
  // Block A
  c := TMyObject1;

  p := c.Create;
  try
    p.Init;
  finally
    FreeAndNil(p);
  end;

  // Block B
  c := TMyObject2;
  p := c.Create;
  try
    try
     p.Init;
    except
      on E: EAbstractError do
      begin
        E := nil;
      end;
    end;
  finally
    FreeAndNil(p);
  end;
end.


Это сообщение отредактировал(а) cemick - 20.11.2009, 12:51
PM MAIL WWW   Вверх
Budy
Дата 20.11.2009, 13:36 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Опытный
**


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

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



cemick, это тоже хороший способ, подобный мне уже предлагали. Но я выяснил, что при дебаге он не удобен. У меня около ста объектов создается таким образом при старте программы smile
В любом случае спасибо.



--------------------
Как ты назовешь свой корабль, так на нем и напишут
user posted image
PM MAIL WWW ICQ   Вверх
cemick
Дата 20.11.2009, 14:37 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Опытный
**


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

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



Цитата(Budy @  20.11.2009,  13:36 Найти цитируемый пост)
cemick, это тоже хороший способ, подобный мне уже предлагали. Но я выяснил, что при дебаге он не удобен. У меня около ста объектов создается таким образом при старте программы 
В любом случае спасибо.

Я не к тому, что надо использовать try except EAbstractError(1. Можно добавить в список исключений которые не будут отлавливаться дебагером 2. Кто же знал что вам не важно,  абстарктный метод или нет), а я к тому, что зачем вам работа с указателями, нафига GetMem и прочие, так писать просто не красиво.
PM MAIL WWW   Вверх
Budy
Дата 23.11.2009, 06:14 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Опытный
**


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

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



Цитата(cemick)
1. Можно добавить в список исключений которые не будут отлавливаться дебагером

Хм... было бы полезно узнать как это сделать.

Цитата(cemick)
а я к тому, что зачем вам работа с указателями, нафига GetMem и прочие, так писать просто не красиво.

Привычка работать с памятью привязалась ко мне еще с Pascal'я. Более надеждного и удобного способа управления объектами для себя лично не вижу.


--------------------
Как ты назовешь свой корабль, так на нем и напишут
user posted image
PM MAIL WWW ICQ   Вверх
cemick
Дата 23.11.2009, 09:45 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Опытный
**


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

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



Цитата(Budy @  23.11.2009,  06:14 Найти цитируемый пост)
Хм... было бы полезно узнать как это сделать.

Tools->Debuging Options -> Language Exceptions (Это в семерке)

Цитата(Budy @  23.11.2009,  06:14 Найти цитируемый пост)
Привычка работать с памятью привязалась ко мне еще с Pascal'я. Более надеждного и удобного способа управления объектами для себя лично не вижу. 

Это не есть плюс, теряется наглядность и прозрачность кода, повышается вероятность ошибки

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


Эксперт
***


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

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



Вообще-то для этих целей есть такая вещь, как виртуальный конструктор и class of.


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


Опытный
**


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

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



Цитата(CodeMonkey @  23.11.2009,  19:12 Найти цитируемый пост)
Вообще-то для этих целей есть такая вещь, как виртуальный конструктор и class of.

Может у вас есть интересные примеры. Прошу выкладывайте  smile 


--------------------
Как ты назовешь свой корабль, так на нем и напишут
user posted image
PM MAIL WWW ICQ   Вверх
CodeMonkey
Дата 24.11.2009, 12:04 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Эксперт
***


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

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



Да пример-то будет почти так же, как у вас. Только уберите Init, засуньте его код в конструктор и объявите Create виртуальным.
Код
type
  TMyObject = class
    constructor Create; virtual;
  end;

  TMyClass = class of TMyObject;

  TMyObject1 = class(TMyObject)
    constructor Create; override;
  end;

  TMyObject2 = class(TMyObject)
    // Нет метода инициализцаии
  end;

implementation

constructor TMyObject.Create;
begin
  inherited Create;
end;

constructor TMyObject1.Create;    
begin
  inherited Create;
  ShowMessage('Init');
end;

var
  p : TMyObject;
  c : TMyClass;
begin
  // Block A
  c := TMyObject1;
  p := c.Create;
  FreeAndNil(p);

  // Block B
  c := TMyObject2;
  p := c.Create;
  FreeAndNil(p);
end.




--------------------
Опытный программист на C++ легко решает любые не существующие в Паскале проблемы.
PM MAIL WWW ICQ Skype GTalk Jabber   Вверх
Ответ в темуСоздание новой темы Создание опроса
Правила форума "Delphi: Общие вопросы"
SnowyMetalFan
bemsPoseidon
Rrader

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

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

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

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


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

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


 




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


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

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