Главная страница
    Top.Mail.Ru    Яндекс.Метрика
Форум: "Основная";
Текущий архив: 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
15-1323549004
Юрий
2011-12-11 00:30
2012.04.15
С днем рождения ! 11 декабря 2011 воскресенье


15-1323592147
alexdn
2011-12-11 12:29
2012.04.15
Ява скрипт


2-1324424597
Gu
2011-12-21 03:43
2012.04.15
overload в dll


1-1291134936
tadalex
2010-11-30 19:35
2012.04.15
Размер панели в StatusBar e


15-1323380858
Baks
2011-12-09 01:47
2012.04.15
Как лучше хранить картинки используемые в программе?





Afrikaans Albanian Arabic Armenian Azerbaijani Basque Belarusian Bulgarian Catalan Chinese (Simplified) Chinese (Traditional) Croatian Czech Danish Dutch English Estonian Filipino Finnish French
Galician Georgian German Greek Haitian Creole Hebrew Hindi Hungarian Icelandic Indonesian Irish Italian Japanese Korean Latvian Lithuanian Macedonian Malay Maltese Norwegian
Persian Polish Portuguese Romanian Russian Serbian Slovak Slovenian Spanish Swahili Swedish Thai Turkish Ukrainian Urdu Vietnamese Welsh Yiddish Bengali Bosnian
Cebuano Esperanto Gujarati Hausa Hmong Igbo Javanese Kannada Khmer Lao Latin Maori Marathi Mongolian Nepali Punjabi Somali Tamil Telugu Yoruba
Zulu
Английский Французский Немецкий Итальянский Португальский Русский Испанский