Форум: "Потрепаться";
Текущий архив: 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