Модераторы: Daevaorn

Поиск:

Ответ в темуСоздание новой темы Создание опроса
> ФАБРИКА КЛАССОВ 
:(
    Опции темы
NULL
Дата 17.9.2003, 10:31 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Шустрый
*


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

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



Что это такое?
PM MAIL ICQ   Вверх
TaTaP
Дата 17.9.2003, 10:45 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Шустрый
*


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

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



В COM это такой класс с определенным интерфейсом, который может создавать классы. По идее только он и имеет право создавать новые объекты. Обычно реализуется разработчиком, т.к. только он в курсе того, как именно создаются его классы...
P.S. А вообще фабрика классов - это один из шаблонов проектирования... Как-то давно я писал программу, САМ придумал этот прием и был очень горд за себя, а оказалось, что это давным-давно все знают...
PM MAIL   Вверх
NULL
Дата 17.9.2003, 11:09 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Шустрый
*


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

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



т.е. можно во время работы аплета создавать новые классы.....
PM MAIL ICQ   Вверх
DENNN
Дата 17.9.2003, 11:14 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Эксперт
****


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

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



Нет, можно создать новые экземпляры классов.
А в COM, это значит, что можно создать новые экземпляры объектов о которых тебе неизвестно ничего кроме их методов.
PM ICQ   Вверх
NULL
Дата 17.9.2003, 11:36 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Шустрый
*


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

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



а для чего нужно?
PM MAIL ICQ   Вверх
DENNN
Дата 17.9.2003, 12:02 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Эксперт
****


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

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



Естественно, для того чтоб воспользоваться методами этих объектов smile.gif.
Обычно, ты сам не можешь (или не хочешь smile.gif ) создавать экземпляры каких-то объектов или классов.
Если говорить о COM, то твоя программа совершенно не беспокоиться о том, где и как создан зарошенный тобой объект: внутри твоего процесса, на локальной машине или вообще где-то в сети. Она получает запрошенный объект, использует и возвращает назад.
PM ICQ   Вверх
NULL
Дата 17.9.2003, 12:14 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Шустрый
*


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

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



спасибо
PM MAIL ICQ   Вверх
RAN
Дата 17.9.2003, 14:11 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Опытный
**


Профиль
Группа: Экс. модератор
Сообщений: 709
Регистрация: 14.3.2003
Где: Щёлково Моск.обл.

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



Что значит "спасибо"? А я? Я тоже хочу поумничать smile.gif .

Чтоб не вдаваться в подробности COM. Смоделируем следующую задачу:
Вы разработали программу, работающую с некоторым объектом реального мира. Например, это компьютерная игра в которой есть злые персонажи (управляемые Вашей прогой), бегающие за добрым (управляется user'ом). Написали класс для персонажа игры
Код

class CPerson {
private:
   ....... Какие-то переменные ............
   ....... остаток жизни, возможности и т.п. ................
public:
   ........ Методы класса .......................
   virtual bool CanWalkThroughTheGate(); //метод, возвращающий может ли сейчас персонаж проходить сквозь стены
   ............................
};


Наследовали от этого класса кучу других (для разных типов персонажей). И тут Вам приходит мысль. А как бы сделать так, чтоб в будущем для добавления новых героев не надо было дорабатывать и перекомпилировать программу? А достаточно бы было написать для них новый класс и сразу использовать в редакторе миссий и игре. Тут решений, конечно много, но приведу одно, отражающее суть фабрики классов.

Можно вынести реализацию классов персонажей в DLL или DLL'ы. И написать в ней фабрику классов. Обычно она реализуется отдельным классом. Вот как она могла бы выглядить в нашей программе (в COM фабрика имеет другой вид и жёстко определённый интерфес):
Код

class CPersonFactory //фабрика персонажей. Чтоб не путали с COM'овской IClassFactory
{
private:
   static const char **PersonNames; //Имена персонажей, реализованных в DLL
public:
   const char** getPersonNames() {return PersonNames;}
   CPerson* getPerson(const char* Name);
};
static const char *CPersonFactory::PersonNames[] = { "EvilGnome", "Fright", 0 };
CPerson* CPersonFactory::getPerson(const char* Name)
{
   const char** names = PersonNames;
   while(*names && strcmp(*names, Name)!=0)
       names++;
   switch(names - PersonNames) {
       case 0: return static_cast<CPerson*>(new CEvilGnomePerson); //где CEvilGnomePerson наследнованный из CPerson
                                                                                                                        //класс, реализующий персонаж "Злой Гномик"
       case 1: return static_cast<CPerson*>(new CFrightPerson); //где CFrightPerson - страшилка
       }
   return 0; //Такой персонаж DLL не поддерживает
}


Теперь в DLL помещаем классы CEvilGnomePerson и CFrightPerson. И всё.
То, как сделал я - не стандарт. Здесь каждый придумывает свой алгоритм.
Сама DLL должна содержать глобальный экземпляр фабрики и функцию, возвращающую указатель на него.
Код

#include ............

static CPersonFactory PersonFactory;

СPersonFactory* GetPersonFactory()
{
   return &PersonFactory;
}


Игра, загружаясь сама, загружает DLL и, вызвав GetPersonFactory, получает указатель на фабрику. Ну, дальше, я думаю, понятно.

P.S. COM и IClassFactory - это отдельная история.
PM MAIL ICQ   Вверх
Step
Дата 17.9.2003, 14:22 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Эксперт
****


Профиль
Группа: Экс. модератор
Сообщений: 5151
Регистрация: 26.9.2002
Где: дурдом.UA

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



RAN, проверю и пойдет наверное в факю


--------------------
- Дурак учится на своих ошибках, умный на чужих.
 - умные учатся у дураков
PM MAIL ICQ   Вверх
NULL
Дата 17.9.2003, 14:55 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Шустрый
*


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

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



RAN, полезная штука =)
PM MAIL ICQ   Вверх
Vyacheslav
Дата 17.9.2003, 16:26 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Эксперт
****


Профиль
Группа: Экс. модератор
Сообщений: 2124
Регистрация: 25.3.2002
Где: Москва

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



Вот еще одна схема реализации фабрики. Примечание : Это только набросок, а не рабочий код.
Здесь появление нового класса не затрагивает код фабрики, но перед использование фабрики класс нужно зарегистрировать
Код

//нижеследующий код менять при появлении нового класса не требуется
class TBaseClass;
typedef  TBaseClass* (*TCreateFunction)(void);
typedef   map<string, TCreateFunction>  TFunctionMap;
class TBaseClass
{
public:
 TBaseClass(){}
 static string ClassName( ) {return string("BaseClass");}
 static  TBaseClass* Create(void) { return new TBaseClass; }
};

class FabricClass
{
private:
TFuctionMap m_Map;
public:
static void Register(string str, TFunctionMap fun)
{
      m_Map.insert(str, fun);
}
static TBaseClass* Create(string str)
{
   TFunctionMap::iterator i = m_Map.find(str);
    if (i)
    {
       TFunctionMap func = i.second;
       return (*func)();
    }
    return NULL;  
}
}  
//здесь кончается неизменяемый код

// далее идет только то, что касается  конкретно классов

class TBaseClass1 : public TBaseClass
{
public:
 TBaseClass1():TBaseClass(){}
 static string ClassName( ) {return string("BaseClass1");}
 static  TBaseClass* Create(void) { return new TBaseClass1; }
};

class TBaseClass2 : public TBaseClass
{
public:
 TBaseClass2():TBaseClass(){}
 static string ClassName( ) {return string("BaseClass2");}
 static  TBaseClass* Create(void) { return new TBaseClass2; }
};

//теперь используем
//сначала регистрация классов в фабрике

TFabricClass::Register(TBaseClass::ClassName(); &(TBaseClass::Create));
TFabricClass::Register(TBaseClass1::ClassName(); &(TBaseClass1::Create));
TFabricClass::Register(TBaseClass2::ClassName(); &(TBaseClass2::Create));

TBaseClass* base = TFabricClass::Create(string("BaseClass"));
TBaseCalss* base1 = TFabricClass::Create(string("BaseClass1"));
TBaseCalss* base2 = TFabricClass::Create(string("BaseClass2"));



--------------------
С уважением, Вячеслав Ермолаев
PM MAIL WWW ICQ   Вверх
NULL
Дата 17.9.2003, 16:39 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Шустрый
*


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

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



Vyacheslav если я пральна понял объект TFabricClass может использовать методы TBaseClass1 и
TBaseClass..... типа наследует два класса?
PM MAIL ICQ   Вверх
RAN
Дата 17.9.2003, 17:07 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Опытный
**


Профиль
Группа: Экс. модератор
Сообщений: 709
Регистрация: 14.3.2003
Где: Щёлково Моск.обл.

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



Цитата
если я пральна понял объект TFabricClass может использовать методы TBaseClass1 и
TBaseClass..... типа наследует два класса

Нет, там функции описаны как static. При регистрации класса адрес функции, создающей класс, запоминается в контейнере. Фабрика потом эту функцию вызывает. Никого наследования.

P.S. Там, кстати, Vyacheslav очепятку допустил. Надо static void Register(string str, TCreateFunction fun) вместо static void Register(string str, TFunctionMap fun).

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


Эксперт
****


Профиль
Группа: Экс. модератор
Сообщений: 2124
Регистрация: 25.3.2002
Где: Москва

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



И возможно не одну. Этот код я уже приводил, и перенес обычным копированием из подобной же темы. И тогда я его набивал не лету. Так что возможны ошибки smile.gif . Этот код можно рассматривать как общую идею реализации фабрики классов


--------------------
С уважением, Вячеслав Ермолаев
PM MAIL WWW ICQ   Вверх
Vyacheslav
Дата 17.9.2003, 17:19 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Эксперт
****


Профиль
Группа: Экс. модератор
Сообщений: 2124
Регистрация: 25.3.2002
Где: Москва

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



Кстати в С++BuilderX появилась такая штука, как визард паттернов. Нужен тебе ,например, Singleton, нажимаешь кнопочку и шаблон к твоим услугам. Похоже в этот визард можно добавлять свои паттерны


--------------------
С уважением, Вячеслав Ермолаев
PM MAIL WWW ICQ   Вверх
Ответ в темуСоздание новой темы Создание опроса
Правила форума "С++:Общие вопросы"
Earnest Daevaorn

Добро пожаловать!

  • Черновик стандарта C++ (за октябрь 2005) можно скачать с этого сайта. Прямая ссылка на файл черновика(4.4мб).
  • Черновик стандарта C (за сентябрь 2005) можно скачать с этого сайта. Прямая ссылка на файл черновика (3.4мб).
  • Прежде чем задать вопрос, прочтите это и/или это!
  • Здесь хранится весь мировой запас ссылок на документы, связанные с C++ :)
  • Не брезгуйте пользоваться тегами [code=cpp][/code].
  • Пожалуйста, не просите написать за вас программы в этом разделе - для этого существует "Центр Помощи".
  • C++ FAQ

Если Вам понравилась атмосфера форума, заходите к нам чаще! С уважением, Earnest Daevaorn

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


 




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


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

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