Главная страница
    Top.Mail.Ru    Яндекс.Метрика
Форум: "Потрепаться";
Текущий архив: 2002.04.11;
Скачать: [xml.tar.bz2];

Вниз

Создание экземпляра класса по имени (ClassRef)   Найти похожие ветки 

 
limon   (2002-03-05 11:19) [0]

Некоторое время назад в форуме был спор Delphi vs C++.
Как пример приводился кусок кода по созданию экземпляра класса по имени класса, что-то типа фабрики классов внутри TObject.
Не могли бы вы повторить, а то никак не могу найти.


 
VuDZ   (2002-03-05 11:42) [1]

в кратце о создание класса по его имени:
в каждом классе объявим два метода:
static Create() {return new ThisClassName();}
и напрмиер virtual char * GetClassName() {return "ThisClassName";}

далее создаем класс RunTimeInformationClass в обязанности которого
входит вести список (мэпку- map) всех зарегестрированных в нем классов. (т.е. ставить в соответсвие "ClassName" и метод ClassName::Create.

осталось зарегестрировать все классы до того, как начнет работать программа.
это делаеться например прописав глобально для каждого из классов некоторую переменную, конструктор которой и сделает все необходимые дейтсвия.
например RunTimeInformationClass ClassNameRegister("ClassName", ClassName::Create);

для удобства все декларации обертываем в макросы:
например так


код:

typedef XObject * (*CLASS_CREATOR)();

#define REGISTER_CLASS(__xClass) \
XClassFactory reg##__xClass(#__xClass, (CLASS_CREATOR)__xClass::Creator)

#define DECLARE_RUNTIMECREATE(__xClass) \
static __xClass * Creator() {return new __xClass();} \
virtual char * GetClassName() {return #__xClass;}



что приводт к следующему:

код:
//header class MyNewClass : public XObject{
public:DECLARE_RUNTIMECREATE(MyNewClass);
};
//cpp
REGISTER_CLASS(MyNewClass);


PS не было никакого спора :>
PPS на делфи это перенести не сложно, если понять мысль


 
Алексей Петров   (2002-03-05 12:31) [2]

> VuDZ ©
А вот здесь пример на С++ не уместен :)

В Delphi есть виртуальные конструкторы и штатный метод GetClassName.

На них и нужно строить игру. А вот от регистрации врядли удастся куда деться (если хаккерские приемы не применять)


 
MBo   (2002-03-05 12:47) [3]

идею видел у Vuk-а

procedure TForm1.Button1Click(Sender: TObject);
type
TWCClass = class of TWinControl;
var
Obj:TWinControl;
ObjClass:TWCClass;
begin
RegisterClass(TButton);
RegisterClass(TEdit);
ObjClass:=TWCClass(GetClass(edit1.text));//пишем или tedit или tbutton
if ObjClass<>nil then begin
Obj:=ObjClass.Create(self);
Obj.Parent:=self;
Obj.SetBounds(10,10,100,20);
end;
end;


 
VuDZ   (2002-03-05 12:54) [4]

2Алексей Петров ну я общий смысл показал :>
тут С++ т и нету, так пара строк, основной момент - все классы должны быть зарегестрированы у некого диспечера


 
MBo   (2002-03-05 13:03) [5]

>limon
кое-что есть в help по
class of


 
Алексей Петров   (2002-03-05 13:08) [6]

Это понятно. Но данный случай - один из тех, очень редких, когда строчки кода на С++ не разъясняют мысль, а наоборот усложняют понимание сообщения :)

К стати в качестве головоломки:
А слабо сделать это без регистрации? Спрашиваю только про идею, т.к. имплементация её будет сложновата.


 
VuDZ   (2002-03-05 13:12) [7]

Скоро вернусь - подумаю.
Т.е. надо создать класс по его имени и всё, без регитрации где-нибудь и пр.?


 
Алексей Петров   (2002-03-05 14:36) [8]

Совсем в общем случаи - врядли получиться. Давайте наложим ограничение, что объект - потомок от TComponent, например.



 
Vuk   (2002-03-05 14:58) [9]

to VuDZ:
>ну я общий смысл показал
В Object Pascal общий даже общий смысл другой получается. :o)

to Алексей Петров:
>А слабо сделать это без регистрации? Спрашиваю только про идею,
>т.к. имплементация её будет сложновата.
Теоретически, конечно, возможно все. :o) Как Вы уже заметили, можно попробовать что нибудь из "хакерских" приемов - найти все ссылки на классы покопавшись в памяти, например. Но это, видимо, будет сильно зависеть от версии компилятора. Вопрос в другом - насколько это реально нужно?
Кстати, при загрузке формы классы создаются без всякой регистрации, но для этого у любого класса с включенной RTTI имеется таблица классов полей, в которую попадают ссылки на классы для всех полей, которые расположены в секцию published.



 
limon   (2002-03-05 14:59) [10]

Всем спасибо.
Мысль пошла.


 
VuDZ   (2002-03-05 15:06) [11]

первое приближение - не совсем по имени...

class parent
{
public:
virtual void Do(){
printf("parent"s Do()\n");
};
protected:
private:
};

class classA : parent
{
public:
classA(){
printf("classA created\n");
};

void Do(){
printf("some method of A\n");
};
protected:
private:
};

class classB : parent
{
public:
classB(){
printf("classB created\n");
};

void Do(){
printf("some method of B\n");
};
protected:
private:
};

#define makeclass(a)\
(parent*)new class##a();

int main(){
parent* p = makeclass(A);
p->Do();
getch();
}


 
vuk   (2002-03-05 15:20) [12]

to VuDZ:
Опять не то. Вы создаете экземпляр при помощи макроса. Чем все это отличается от явного создания экземпляра? Похоже, что ничем...


 
VuDZ   (2002-03-05 15:29) [13]

I understand :<


 
Алексей Петров   (2002-03-05 15:50) [14]

Вот о том и речь, что отвечать на вопрос по нюансам Object pascal на С++ не стоит :)
Вот по WinAPI - там все равно.


 
VuDZ   (2002-03-05 15:54) [15]

всё, уйду в монастырь - буду на С писать.... правда и в нём сделаю классы :>


 
MBo   (2002-03-05 16:02) [16]

>Алексей Петров
Интересно - ты нашел решение (только наличие/отсутствие)?



 
VuDZ   (2002-03-05 16:19) [17]

может вот это рассматривать как шутку юмора - тут почти обратное наследование:

class parent
{
public:
virtual void Do(){
printf("parent"s Do()\n");
};

static parent* GetClass(std::string cl){
if (cl == "parent")
return new parent;

else
return NULL;
}
protected:
private:
};

class classA : parent
{
public:
classA(){
printf("classA created\n");
};

void Do(){
printf("some method of A\n");
};

static void* GetClass(std::string cl){
if (cl == "classA")
return new classA;

else
return parent::GetClass(cl);
}
protected:
private:
};

class classB : classA
{
public:
classB(){
printf("classB created\n");
};

void Do(){
printf("some method of B\n");
};


static void* GetClass(std::string cl){
if (cl == "classB")
return new classB;

else
return classA::GetClass(cl);
}
protected:
private:
};

int main(){
parent* p = (parent*)classB::GetClass("classB");
if (!p)
return;

p->Do();
getch();
}


 
Алексей Петров   (2002-03-05 16:30) [18]

> VuDZ © (05.03.02 16:19)
> может вот это рассматривать как шутку юмора - тут почти обратное наследование:
Ну намудрил!!! :)
А обратное наследование круче всего в ATL сделано. OLEDB провайдер как-то ваял - так голову сломал на этих выкрутасах :)

> VuDZ © (05.03.02 15:54)
> всё, уйду в монастырь - буду на С писать.... правда и в нём сделаю классы :>
Это же извращение. VMT руками поддерживать... Для этого ведь компилятор и нужен :)
Хотя я на TASM-е с объектами программировал немного :)

> MBo © (05.03.02 16:02)
> Интересно - ты нашел решение (только наличие/отсутствие)?
Я идею не реализовывал в коде, но возможность исследовал и сделал вывод о возможности решения.


 
MBo   (2002-03-05 16:36) [19]

а ограничения?
Если мы в runtime попросим создать компонент, скажем, stringgrid, о котором Exe никакого понятия не имеет - и финиш...


 
VuDZ   (2002-03-05 16:41) [20]

2Алексей Петров колись, что заидея?


> а ограничения?
> Если мы в runtime попросим создать компонент, скажем, stringgrid,
> о котором Exe никакого понятия не имеет - и финиш...

тогда к нам прийдёт генерал Протекшин Фаулт :>


 
Алексей Петров   (2002-03-05 16:46) [21]

> MBo, VuDZ
Прошу в новую ветку.



Страницы: 1 вся ветка

Форум: "Потрепаться";
Текущий архив: 2002.04.11;
Скачать: [xml.tar.bz2];

Наверх





Память: 0.5 MB
Время: 0.01 c
1-32781
Rooman
2002-03-23 17:54
2002.04.11
Отсылка сообщения через зад:)


1-32771
snoup
2002-03-30 22:34
2002.04.11
Дайте пожалуйста простенький кодик как загружать и сохранять данн


14-32979
Стас
2002-03-04 08:32
2002.04.11
Исходники для работы с dBASE в Паскале


7-32995
Voldemar
2002-01-17 19:48
2002.04.11
Измерение загрузки и температуры процессора


1-32723
LazorenkoX
2002-03-29 22:55
2002.04.11
Маус (только не обижайтесь)





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
Английский Французский Немецкий Итальянский Португальский Русский Испанский