LINUX.ORG.RU

Класс «плагина» - как наилучшим образом запилить?

 ,


0

2

А подскажите, знатоки C++

Надо сделать такое:

Есть у меня в приложении меню и несколько других стандартных хуков Надо сделать возможность создавать расширения, которые будут автоматом регистрироваться в меню (и других местах) без явного прописывания в списках.

То есть типа

class UserExtension1: public Extension {
...
};

Чтобы можно было прописать имя пункта меню, другие параметры, просто в разных .cpp файлах.

Я так понимаю можно добавить метод регистрации класса как статический метод и дёргать через макрос через класс-конструктор:

#define MENU_REGISTER(c, name) \
static void register_menu(MenuData *menu) \
{ \
    menu->Register(construct_## c, name) \
} \
static c * construct_ ## c () \
{ \
    return new c(); \
}
#define MENU_CONSTRUCT(c) \
class menu_ ## c { \
    menu_ ## c (MenuData *menu) \
    { \
        c::register_menu(menu); \
    } \
}; \
menu_ ## c c ## _data(global_menu);

Но нет ли способа поэлегантнее? Да, с++ использую редко.

★★★★★

Я себе так как-то делал чтобы без макросов. Вторым параметром шаблона можно попробовать передавать места где класс должен регистрироваться.

xaizek ★★★★★
()
Ответ на: комментарий от slapin

Это у меня два раза registered выводит:

#include <iostream>

template <class C>
class AutoRegisteredCommand
{
   static const bool invokeRegister;
   friend void doRegistration(AutoRegisteredCommand * = 0) {
       std::cout << "registered\n";
   }
   friend void forceRegistration(const bool & = invokeRegister,
                                 AutoRegisteredCommand * = 0) { }
};

template <class C>
const bool AutoRegisteredCommand<C>::invokeRegister = (doRegistration(static_cast<AutoRegisteredCommand *>(0)), true);

class A : AutoRegisteredCommand<A>
{
};

class B : AutoRegisteredCommand<B>
{
};

int
main(void)
{
    return 0;
}
xaizek ★★★★★
()
Ответ на: комментарий от xaizek

Так то да, но тут если нужно вызвать метод класса, не будет ли облом? И тут получается нет доступа к инстансу... Тут получается придется добавлять статические константы прямо в основной класс чтобы зарегистрировать. С другой стороны не нужна фабрика,что подкупает, конечно. Но нельзя передать другой объект как параметр при регистрации, то есть нужен синглтон...

slapin ★★★★★
() автор топика
Ответ на: комментарий от slapin

Сделал (new C())->f();, сработало. Что-то статическое нужно, это да. Это может быть какой-нибудь вектор объектов, умеющих создавать эти C с параметрами, а doRegistration() просто создавал бы их.

xaizek ★★★★★
()

Продумай интерфейс плагина. Делаешь библиотеку. Твоя программа при обнаружении плагина делает dlopen и вперёд.

В идеале твоему меню должно быть без разницы, плагин там регистрируется или нет. (По хорошему - все плагины, только одни сразу слинкованы, другие подгружаются.)

invy ★★★★★
()
Последнее исправление: invy (всего исправлений: 1)
Ответ на: комментарий от invy

Мне надо без dlopen. Мне надо чтобы я отнаследовался от класса, определил свои нужные методы и оно само регистрировалось везде где нужно, в меню и прочих местах.

Решение от xaizek мне кажется близким к идеалу.

slapin ★★★★★
() автор топика
Вы не можете добавлять комментарии в эту тему. Тема перемещена в архив.