Форум: "Основная";
Текущий архив: 2012.04.15;
Скачать: [xml.tar.bz2];
ВнизМанипулирование метаклассами Найти похожие ветки
← →
VLK32 (2010-11-27 14:32) [0]Помогите разобраться с такой проблемой. Вот код:
TClass32 = class(TObject) ... тут есть свой конструктор
TPlayer = class(TClass32) ... и тут есть свой конструктор
TMeta32 = class of TClass32;
var FClass : TMeta32;
FClass := TPlayer;
FClass.Create; // здесь вызовется конструктор для класса TClass32. Это проверено.
Вопрос. Почему так? Как имея ссылку на класс создать именно его экземпляр?
← →
VLK32 (2010-11-27 14:52) [1]Некоторые уточнения.
если FClass := TPlayer;
то FClass.Create;
создаст объект именно класса TPlayer но вызовет для него конструктор класса TClass32, т.е. экземпляр будет правильного типа но он будет не полностью инициализирован, т.к. конструктор TPlayer не вызван.
← →
MBo © (2010-11-27 15:22) [2]конструктор виртуален?
← →
VLK32 (2010-11-27 15:39) [3]>> конструктор виртуален?
нет
но почему я могу присвоить FClass := TPlayer; а потом не могу через эту переменную вызвать конструктор именно для TPlayer. По FClass.Create;
вызывается конструктор именно класса TClass32, но! внутри самого конструктора все виртуальные методы вызываются правильно, т.е. для TPlayer. Короче говоря, цирк. Для меня загадка почему метакласс не может вызвать нужный конструктор.
Проблему я обошел, но код стал чуть более громоздким, а хотелось как можно проще.
← →
_Юрий (2010-11-27 15:43) [4]
> Для меня загадка почему метакласс не может вызвать нужный
> конструктор.
потому что конструктор не виртуален
сделай его виртуальным, и будет вызываться нужный конструктор.
собственно говоря, это и есть единственная причина делать конструкторы виртуальными - необходимость вызова нужного при создании через метакласс.
← →
Anatoly Podgoretsky © (2010-11-27 15:47) [5]> VLK32 (27.11.2010 14:32:00) [0]
Это наследование. Если не перекрыто, то берется от родителя.
← →
VLK32 (2010-11-27 16:11) [6]Ок. Понял. Сейчас попробую. Спасибо за подсказку.
← →
Ega23 © (2010-11-29 12:13) [7]
> Для меня загадка почему метакласс не может вызвать нужный
> конструктор.
Конструктор, если очень грубо, суть такой же метод. Тебя же не удивляет такое поведение?TClass1 = class
public
procedure Foo;
end;
TClass2 = class (TClass1)
public
procedure Foo;
end;
procedure TClass1.Foo;
begin
ShowMessage("TClass1.Foo;")
end;
procedure TClass2.Foo;
begin
ShowMessage("TClass2.Foo;")
end;
var
value: TClass1;
begin
value := TClass2.Create;
try
value.Foo;
finally
value.Free;
end;
end;
Или таки удивляет?
← →
Leonid Troyanovsky © (2010-11-29 21:58) [8]
> Ega23 © (29.11.10 12:13) [7]
> Конструктор, если очень грубо, суть такой же метод.
К людям надо мягше, а на вопросы смотреть - ширше.
Классовый метод, на минуточку (сначала "пельмени",
а уж потом - "равиоли").
--
Regards, LVT.
← →
Ega23 © (2010-11-30 10:56) [9]
> Классовый метод, на минуточку
У него Self не на класс указывает. В отличие от классового метода.
В общем, не всё так просто.
← →
Leonid Troyanovsky © (2010-11-30 21:16) [10]
> Ega23 © (30.11.10 10:56) [9]
> В общем, не всё так просто.
Простоты и не обещали.
Сначала классовый метод, а уж потом - метод класса,
возвращающий и инициализирующий экземпляр класса.
--
Regards, LVT.
← →
han_malign (2010-12-02 11:04) [11]добавлю 5 копеек:
> но почему я могу присвоить FClass := TPlayer; а потом не
> могу через эту переменную вызвать конструктор именно для
> TPlayer.
- потому, что Pointer(TPlayer) - по сути, есть указатель на VMT(таблицу виртуальных методов) - и этим все сказано...
← →
oxffff © (2010-12-02 12:47) [12]
> han_malign (02.12.10 11:04) [11]
> добавлю 5 копеек:
>
> > но почему я могу присвоить FClass := TPlayer; а потом
> не
> > могу через эту переменную вызвать конструктор именно для
>
> > TPlayer.
>
> - потому, что Pointer(TPlayer) - по сути, есть указатель
> на VMT(таблицу виртуальных методов) - и этим все сказано.
> ..
Pointer(TPlayer) - это двойной указатель на VMT.
← →
han_malign (2010-12-02 16:46) [13]
> Pointer(TPlayer) - это двойной указатель на VMT.
- двойной - у экземпляра: PPointer(TPlayer.Create())^ = Pointer(TPlayer)
← →
_oxffff (2010-12-02 20:51) [14]
> han_malign (02.12.10 16:46) [13]
>
> > Pointer(TPlayer) - это двойной указатель на VMT.
>
> - двойной - у экземпляра: PPointer(TPlayer.Create())^ =
> Pointer(TPlayer)
Точно!
Даже сейчас смотрел на TPlayer в полной уверенности что это экземпляр. :)
Вот она невнимательность.
Страницы: 1 вся ветка
Форум: "Основная";
Текущий архив: 2012.04.15;
Скачать: [xml.tar.bz2];
Память: 0.48 MB
Время: 0.003 c