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

Поиск:

Ответ в темуСоздание новой темы Создание опроса
> constructor/destructor, кто виртуальней? 
:(
    Опции темы
Earnest
Дата 12.7.2005, 17:22 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Эксперт
****


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

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



Сам по себе switch ничем не плох, просто конструкции, где используется switch, расширяются исключительно вручную.
С помощью шаблонов же можно обеспечить такую масштабируемость, что при добавлении новых производных классов будет изменяться только клиентский код (т.е. код, где этот новый тип объявляется и реализуется).
Что касается производительности, то при создании новых объектов вовсе не выбор выполняемого кода является критичным, а операция выделения памяти и инициализация нового объекта. Очевидно, что для простых объектов типа int и огород городить нечего. Так что на издержки выбора из map можно смело наплевать. Вот пример очень простой фабрики:

Код

// ----- BaseFactory.h ----
// базовый класс
class CBase
{
};

// фабрика, которая умеет создавать объекты, производные от CBase
class CFactory
{
    typedef CBase* (*PFNCREATE)();
    typedef std::map<string,PFNCREATE> CRegistry;

public:
    void Insert(const type_info& ti,PFNCREATE fn)
    {
        m_Reg[ti.raw_name()] = fn;
    }

    template <class Type>
    CBase* Create() const
    {
        CRegistry::const_iterator it = m_Reg.find(typeid(Type).raw_name());
        if (it == m_Reg.end()) return 0;
        else return it->second();
    }    
    
private:    
    CRegistry m_Reg;
};

// объект-фабрика (где-нибудь в c-файле нужно поместить definition)
extern CFactory _Factory;

// вспомогательный шаблон, используем рекурсивный шаблон (CRT)
template <class _Result,class _Base>
class _Creatable
{
public:
    static _Base* Create() { return new _Result; }    
};

// вспомогательная обертка для регистрации
template <class TYPE>
struct CRegistrar
{
    CRegistrar()
    {
        _Factory.Insert(typeid(TYPE),TYPE::Create); 
    }
};

#define DECLARE_CREATABLE(Type) CRegistrar<Type> _tmp;

// ------ end of BaseFactory.h --------

// где-нибудь в другом модуле
class CDerive: public CBase, public _Creatable<CDerive,CBase>
{
};

DECLARE_CREATABLE(CDerive);

// используем
void foo()
{
    CBase* p = _Factory.Create<CDerive>();
}


Это пример довольно примитивной фабрики, только для того, чтобы проиллюстрировать идею. Далее можно усложнять: вместо указателя на фукцию использовать объект boost::function, сделать factory синглетоном, добавить варианты создания с параметрами, наконец, параметризовать базовый тип,... просто бесконечные возможности.


--------------------
...
PM   Вверх
Ответ в темуСоздание новой темы Создание опроса
Правила форума "С++:Общие вопросы"
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.0467 ]   [ Использовано запросов: 22 ]   [ GZIP включён ]


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

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