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

Поиск:

Ответ в темуСоздание новой темы Создание опроса
> ООП 
:(
    Опции темы
omickron
Дата 20.7.2011, 18:01 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Шустрый
*


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

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



Имеем: 

Код

type 
  TMyClass = class(TObject);
  TMyClass1=class(TMyClass);
  TMyClass2=class(TMyClass);

var
  my,new:TMyClass;
  
begin
  my := TMyClass1.Create;
  //todo: Задача: в переменной new создать объект того же класса, что и объект my.
  // new := my.ClassType.Create; // не работает, не пускает компилятор, т.к. ClassType = class of TObject
end;


Вопрос: как в переменную засунуть объект такого же класса, что и имеющийся объект?
PM MAIL   Вверх
AKATAN
Дата 20.7.2011, 21:41 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Шустрый
*


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

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



Код

new := TMyClass.Create;

или обращаться к TMyClass нельзя?

Это сообщение отредактировал(а) AKATAN - 20.7.2011, 21:43
PM MAIL ICQ   Вверх
pseud
Дата 21.7.2011, 09:14 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Экспёрт Тыдыщ
***


Профиль
Группа: Завсегдатай
Сообщений: 1175
Регистрация: 18.5.2007
Где: Минск, Беларусь

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



Код

  if my is TMyClass1 then
    new := TMyClass1.Create
  else if my is TMyClass2 then
    new := TMyClass2.Create;



--------------------
Испытание чужого терпения можно считать успешным, если оно лопнуло...
PM MAIL   Вверх
skyboy
Дата 21.7.2011, 14:28 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


неОпытный
****


Профиль
Группа: Модератор
Сообщений: 9820
Регистрация: 18.5.2006
Где: Днепропетровск

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



лучше - воспользоваться паттерном "Прототип". тогда будет типа такого:
Код

source = TMyClass1.create();
target = source.clone();

можно - воспользоваться RTTI и написать что-то навроде:
Код

source = TMyClass1.create();
target = getClass(source.className).create();

но, кажется, только для определенных классов будет работать(в плане иерархии у "подходящих" классов должен быть предком TPersistentClass, кажется)

PM MAIL   Вверх
omickron
Дата 21.7.2011, 17:51 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Шустрый
*


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

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



AKATAN, блин smile просто замечательный ответ smile

pseud, а теперь представьте, что у вас пара десятков наследников TMyClass. Представили? Как будет выглядеть Ваш код?

skyboy, а прототипы разве реализуются в Delphi? Интересует 2007 версия.
Насчёт GetClass - если не ошибаюсь, она вернёт то же значение, что и source.ClassType. А это не срабатывает, как я писал в первом посте.

PM MAIL   Вверх
bems
Дата 22.7.2011, 06:49 (ссылка) |    (голосов:2) Загрузка ... Загрузка ... Быстрая цитата Цитата


Эксперт
****


Профиль
Группа: Комодератор
Сообщений: 3400
Регистрация: 5.1.2006

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



Код

type
  TMyClass = class(TObject);
  TMyMetaclass = class of TMyClass;

  TMyClass1=class(TMyClass);
  TMyClass2=class(TMyClass);
var
  my,new:TMyClass;

begin
  my := TMyClass1.Create;
  new := TMyMetaclass(my.ClassType).Create;
end.

конструктор лучше бы сделать виртуальным


--------------------
Обижено школьников: 8
PM MAIL   Вверх
omickron
Дата 23.7.2011, 12:17 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Шустрый
*


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

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



Спасибо! TMyMetaclass(my.ClassType).Create - то, что надо!

Насчёт виртуального конструктора - вроде он должен обязательно быть для динамического определения типа создаваемого объекта.
Но почему-то в приведённом Вами коде ShowMessage(new.ClassName); показывает "MyClass1". MyClass - просто наследник Tobject, а у него конструктор не виртуальный, обычный.

Блин, почему? smile
PM MAIL   Вверх
bems
Дата 23.7.2011, 13:17 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Эксперт
****


Профиль
Группа: Комодератор
Сообщений: 3400
Регистрация: 5.1.2006

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



потому что my.ClassType равен TMyClass1. Приведение к TMyMetaclass нужно только чтобы выражение удовлетворяло правилам совместимости типов.
А вот тело конструктора выполняется от TMyClass. Сделай такой эксперимент, и увидишь:
Код

program Project14;

{$APPTYPE CONSOLE}

type
  TMyClass = class(TObject)
    constructor Create;
  end;
  TMyMetaclass = class of TMyClass;

  TMyClass1=class(TMyClass)
    constructor Create;
  end;

var
  my,new:TMyClass;

{ TMyClass1 }

constructor TMyClass1.Create;
begin
  inherited;
  writeln('Object: ', Cardinal(Self), ' ClassName: ', ClassName, ' Constructor: TMyClass1.Create');
end;

{ TMyClass }

constructor TMyClass.Create;
begin
  writeln('Object: ', Cardinal(Self), ' ClassName: ', ClassName, ' Constructor: TMyClass.Create');
end;

begin
  my := TMyClass1.Create;
  writeln;
  new := TMyMetaclass(my.ClassType).Create;
  readln
end.


Такой объект я назвал бы калекой. Если сделать конструктор виртуальным - проблема исчезает


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

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

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

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

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


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

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


 




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


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

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