powered by simpleCommunicator - 2.0.61     © 2026 Programmizd 02
Целевая тема:
Создать новую тему:
Автор:
Закрыть
Цитировать
Форумы / C++ [игнор отключен] [закрыт для гостей] / динамическое создание объекта, тип которого указан в виде строки.
25 сообщений из 96, страница 2 из 4
динамическое создание объекта, тип которого указан в виде строки.
    #33853666
MElin
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Akh BarloneAkh, вам нужно автоматизировать построение списка пар "Имя класса"->"Указатель на функцию, возвращающую экземпляр класса" ?

Что-то вроде этого...
макрос DECLARE_DYNCREATE делает примерно тоже самое.
после определения этого макроса внутри класса (потомка Object) возможно создание его создание в рантайм
...
Рейтинг: 0 / 0
динамическое создание объекта, тип которого указан в виде строки.
    #33853716
Akh
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
MElinмакрос DECLARE_DYNCREATE делает примерно тоже самое.
после определения этого макроса внутри класса (потомка Object) возможно создание его создание в рантайм

Внял совету, почитал

А мне его взять то, если я на gcc?
...
Рейтинг: 0 / 0
динамическое создание объекта, тип которого указан в виде строки.
    #33853771
Dmitrii K.
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Akh MElinмакрос DECLARE_DYNCREATE делает примерно тоже самое.
после определения этого макроса внутри класса (потомка Object) возможно создание его создание в рантайм

Внял совету, почитал

А мне его взять то, если я на gcc?
Так то ж MFC ))

Но полезно будет почитать про RTTI от Borland и CRuntimeClass и иже с ним от Microsoft, принципы, реализация... чтоб своё наваять или может под gcc что-то подобное найдёшь.
...
Рейтинг: 0 / 0
динамическое создание объекта, тип которого указан в виде строки.
    #33853935
Akh
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Насколько я понял по afx.h в имплемент имя класса передается не в виде строки. Так, что это не то что нужно.
...
Рейтинг: 0 / 0
динамическое создание объекта, тип которого указан в виде строки.
    #33854484
a_shar
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Гость
AkhА мне его взять то, если я на gcc?
Можешь заюзать Qt, там есть такая возможность, смотри QMetaType у него есть метод construct.
...
Рейтинг: 0 / 0
динамическое создание объекта, тип которого указан в виде строки.
    #33854612
Akh
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
a_sharМожешь заюзать Qt, там есть такая возможность, смотри QMetaType у него есть метод construct.

Там имя класса передается в виде строки?
...
Рейтинг: 0 / 0
динамическое создание объекта, тип которого указан в виде строки.
    #33855566
Фотография blinded
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Задача решается в полсотни строк, причем достаточно элегантно. Идея достаточно проста: заводится статический ассоциативный контейнер, в который в момент загрузки программы заносятся объекты, способные создавать прикладные объекты соответствующего класса. М-да непонятно получилось, лучше посмотреть на код. Там все гораздо понятнее. Могу прислать готовый заголовочный файл с тестовым случаем. Писать vaska@b-k.ru

# ifndef _FACTORY_H
# define _FACTORY_H
# include <map>
// База для вспомогательных классов
// с помощью которых будут создаваться
// прикладные объекты. Умеет также зарегистрировать
// себя в ассоциативном контейнере.
template <typename K, typename T>
class FactoryHelperBase
{
public:
virtual ~FactoryHelperBase() {};
virtual T* clone() const = 0;
protected:
void install(const K&);
};

// Собственно фабрика объектов. К которой следует обращаться
// для создания обьектов, содержит внутри себя map
// вспомогательнвх классов (см выше). Создание нового объекта
// очень элегантно
// MyBase* myBase = Factory<std::string, MyBase>::make(“MyChild”);
template <typename K, typename T>
class Factory
{
public:
typedef FactoryHelperBase<K, T> Creator;
private:
friend class Creator;
typedef std::map<K, Creator*> Buffer;
static Buffer buf;
public:
static T* make(const K& k)
{
typename Buffer::const_iterator i = buf.find(k);
if ( i == buf.end())
return 0;
return i->second->clone();
}
};

template <typename K, typename T>
inline void FactoryHelperBase<K, T>::install(const K& k)
{
Factory<K, T>::buf[k] = this;
}

// Набор макросов с помощью которых в некоторой единице
// компиляции создается фабрика.
// выглядит это так
// DECLARE_FACTORY(std::string, MyBase)
// ADD_FACTORY(“MyClass”, MyClass);
// END_DECLARE_FACTORY
# define DECLARE_FACTORY(K, T) \
namespace \
{ \
typedef Factory<K, T> factory; \
typedef T value_type; \
typedef K key_type; \
factory::Buffer factory::buf;

# define END_DECLARE_FACTORY }

# define ADD_FACTORY(k, t) \
class factoryHelper##t : public factory::Creator \
{ \
public: \
factoryHelper##t() { install(key_type(k)); } \
value_type* clone() const { return new t; } \
}; \
static factoryHelper##t factoryHelper##t##install


# endif // _FACTORY_H
...
Рейтинг: 0 / 0
динамическое создание объекта, тип которого указан в виде строки.
    #33855615
a_shar
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Гость
a_shar AkhА мне его взять то, если я на gcc?
Можешь заюзать Qt, там есть такая возможность, смотри QMetaType у него есть метод construct.
Код: plaintext
1.
2.
3.
4.
5.
6.
7.
    int id = QMetaType::type("MyClass");
    if (id !=  0 ) {
        void *myClassPtr = QMetaType::construct(id);
        ...
        QMetaType::destroy(id, myClassPtr);
        myClassPtr =  0 ;
    }

в объявление класса вставь
Код: plaintext
1.
2.
    int id = qMetaTypeId<QString>(); // id is now QMetaType::QString
    id = qMetaTypeId<MyStruct>(); // compile error if MyStruct not declared
думаю из примера понятно что куда
...
Рейтинг: 0 / 0
динамическое создание объекта, тип которого указан в виде строки.
    #33855908
Фотография blinded
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
a_shar a_shar AkhА мне его взять то, если я на gcc?
Можешь заюзать Qt, там есть такая возможность, смотри QMetaType у него есть метод construct.
Код: plaintext
1.
2.
3.
4.
5.
6.
7.
    int id = QMetaType::type("MyClass");
    if (id !=  0 ) {
        void *myClassPtr = QMetaType::construct(id);
        ...
        QMetaType::destroy(id, myClassPtr);
        myClassPtr =  0 ;
    }

в объявление класса вставь
Код: plaintext
1.
2.
    int id = qMetaTypeId<QString>(); // id is now QMetaType::QString
    id = qMetaTypeId<MyStruct>(); // compile error if MyStruct not declared
думаю из примера понятно что куда
У Qt две беды
1 необхобимость тащить ее с собой, что не всегда оправдано. Например демона написать.
2 возвращает такая фабрика void*. Эта беда пострашнее. Дело в том, что родитель в наследнике может размещаться совсем не 0 смещением. Например в случае множественного наследования. И как в таком случае приводить тип?
PS На attachment тестовый пример повесил
...
Рейтинг: 0 / 0
динамическое создание объекта, тип которого указан в виде строки.
    #33857139
Akh
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
blindedЗадача решается в полсотни строк, причем достаточно элегантно. Идея достаточно проста: заводится статический ассоциативный контейнер, в который в момент загрузки программы заносятся объекты, способные создавать прикладные объекты соответствующего класса. М-да непонятно получилось, лучше посмотреть на код. Там все гораздо понятнее. Могу прислать готовый заголовочный файл с тестовым случаем. Писать vaska@b-k.ru
...


Решение, действительно красивое. Разбираюсь.

Не могу понять почему:
Код: plaintext
1.
2.
3.
4.
5.
6.
g++ -c main.cpp -o main.o
g++ -c f1.cpp -o f1.o
g++ -c f2.cpp -o f2.o
g++ main.o f1.o f2.o -o main
f2.o(.bss+0x0): multiple definition of `Factory<std::basic_string<char, std::char_traits<char>, std::allocator<char> >, Base>::buf'
f1.o(.bss+0x0): first defined here

По всей видимости, компилятор не удиляет внимания наймспейсу из DECLARE_FACTORY?
...
Рейтинг: 0 / 0
динамическое создание объекта, тип которого указан в виде строки.
    #33858939
Фотография blinded
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
И не пытайтесь слинковать две фабкики с одинаковыми параметрами в один исполняемый модуль. Ну ничего не выйдет. Она объявлена все какаого либо namespace. А безымянный namespace в макросах заведен typedef внутри него не пересеклись с кем-нибудь. Рад что понравилосьЖ)
...
Рейтинг: 0 / 0
динамическое создание объекта, тип которого указан в виде строки.
    #33861421
Фотография MasterZiv
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Средствами C++ (самого языка) вам это не сделать. Таких средств нет.
Надо писать . Это называвется Class Factory, это pattern такой, описано в GoF и еще в других источниках. Читайте.
...
Рейтинг: 0 / 0
динамическое создание объекта, тип которого указан в виде строки.
    #33864164
Фотография blinded
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
MasterZivСредствами C++ (самого языка) вам это не сделать. Таких средств нет.
Надо писать . Это называвется Class Factory, это pattern такой, описано в GoF и еще в других источниках. Читайте.
Хотоший совет. Вот только у Банды 4-х как раз switch и нарисован. Лучше почитать Александреску Modern C++ Design ... Там целая глава по этому поводу. А еще интересная фабрика у Дага Шмидта Network Programming using C++ vol 2
...
Рейтинг: 0 / 0
динамическое создание объекта, тип которого указан в виде строки.
    #33864407
maXmo
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Sandro_KВ линуксе что-то подобное можно сделать, это точно. У нас на работе один чел что-то похожее пытался сделать, но у него возникли какие-то проблемы, и это так и не было доделано.угу, мне сказали, в лине нет дллок, есть разделяемые библиотеки, но они грузятся только при загрузке приложения. Akh, я так понял, ты подгружаешь библиотеку в рантайме. Расскажи, как. Интересно.
...
Рейтинг: 0 / 0
динамическое создание объекта, тип которого указан в виде строки.
    #33864754
Akh
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
maXmoугу, мне сказали, в лине нет дллок, есть разделяемые библиотеки, но они грузятся только при загрузке приложения. Akh, я так понял, ты подгружаешь библиотеку в рантайме. Расскажи, как. Интересно.

Я использую статичесткие, т.к. в данном проекте нет смысла использовать разделяемые.

Если интересна эта тема, можно посмотреть например тут .
...
Рейтинг: 0 / 0
динамическое создание объекта, тип которого указан в виде строки.
    #33864798
maXmo
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
эээ... и как ты собираешься с помощью статических библиотек добавлять новый класс без перекомпиляции?
...
Рейтинг: 0 / 0
динамическое создание объекта, тип которого указан в виде строки.
    #33864817
Akh
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
maXmoэээ... и как ты собираешься с помощью статических библиотек добавлять новый класс без перекомпиляции?

[...наивный взгляд...] как blinded объяснял. Мне не нужна перекомпиляция. Только линковка.
...
Рейтинг: 0 / 0
динамическое создание объекта, тип которого указан в виде строки.
    #33864843
Akh
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
компиляция только самого приложения и линковка с библиотеками. да бы не перекомпиливать библиотеки
...
Рейтинг: 0 / 0
динамическое создание объекта, тип которого указан в виде строки.
    #33864942
maXmo
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Akh BarloneAkh, вам нужно автоматизировать построение списка пар "Имя класса"->"Указатель на функцию, возвращающую экземпляр класса" ?Что-то вроде этого...если юзать лишь статические бибки, могу предложить такое...

Код: plaintext
1.
2.
3.
4.
5.
6.
7.
8.
9.
10.
11.
12.
13.
14.
15.
16.
17.
extern int AddToList(char*,IWorkInterface *(*)());

class Class3 : public IWorkInterface
{
 public:
 static IWorkInterface *CreateInstance();
 ...
}

class Class3Reger
{
 public:
 Class3Reger()
 {
  AddToList("Class3",Class3::CreateInstance);
 }
} Class3StartupReger;
функция AddToList одна, строит где-нибудь у себя ассоциативный массив адресов функций. Потом из этого массива можно будет вызвать нужный CreateInstance по имени класса. Объявление Class3StartupReger должно будет вызвать выполнение своего конструктора при загрузке приложения (типа статического кода в джаве). Не знаю, сработает ли это, вроде бы должно прокатить. Давно уже на сяхпп не писал.
...
Рейтинг: 0 / 0
динамическое создание объекта, тип которого указан в виде строки.
    #33864987
maXmo
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
AkhМне не нужна перекомпиляция. Только линковка.но это та же перекомпиляция, только минимизированная. Надо выгружать приложение, запускать мейк...
...
Рейтинг: 0 / 0
динамическое создание объекта, тип которого указан в виде строки.
    #33865082
Akh
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
maXmoНе знаю, сработает ли это, вроде бы должно прокатить. Давно уже на сяхпп не писал.

Работает. Наверно, это будет самый удобный вариант.

Только вопрос. Конструктор этого класса, по времени, как будет по отношению к конструкторам классов, которые будут создаваться статически (во, написал :) )? Раньше, позже или как попало?
...
Рейтинг: 0 / 0
динамическое создание объекта, тип которого указан в виде строки.
    #33866265
maXmo
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
уточни, о каком классе и каких классах ты говоришь (не зря ведь им имена даны :) ). И о каком статическом создании идёт речь? Для строгости стоит напомнить, что классы создаются на стадии компиляции, а глобальные и статические объекты этих классов - на стадии загрузки приложения междй инициализацией кучи и вызовом мейна. Называется это, кажется, global_ctors (на стадии выгрузки, соотв. dtors).
...
Рейтинг: 0 / 0
динамическое создание объекта, тип которого указан в виде строки.
    #33866447
Akh
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Допустим, есть класс ClassMain, который пользует список, формируемый AddToList. И программисту вздумалось создать экземпляр этого класса статически, в конструкторе которого указана строка с названием класса, которого тот должен создать. Соответственно, перед функцией мэйн, будет вызван конструктор, который побежит по списку и будет искать нужный класс. Так же перед функцией мэйн будут созданы классы ClassXReger, которые будут заполнять этот список. Соответственно вопрос - будет ли в этом случае вовремя заполнен список классов?
...
Рейтинг: 0 / 0
динамическое создание объекта, тип которого указан в виде строки.
    #33866842
maXmo
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
гарантии нет (придётся проводить инициализацию ClassMain в две ступени). Возможно, это можно сделать с помощью каких-нибудь прагм (сказать компилятору, чтобы регеры были инициализированы как можно раньше). Возможно даже, порядок инициализации зависит от того, в каком порядке ты указывал библиотеки при линковке.
...
Рейтинг: 0 / 0
динамическое создание объекта, тип которого указан в виде строки.
    #33866873
Akh
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Это плохо. Может каким-то образом средствами С++ можно запретить статическое создание экземпляра?
...
Рейтинг: 0 / 0
25 сообщений из 96, страница 2 из 4
Форумы / C++ [игнор отключен] [закрыт для гостей] / динамическое создание объекта, тип которого указан в виде строки.
Найденые пользователи ...
Разблокировать пользователей ...
Читали форум (0):
Пользователи онлайн (0):
x
x
Закрыть


Просмотр
0 / 0
Close
Debug Console [Select Text]