crossplatform.ru

Здравствуйте, гость ( Вход | Регистрация )

2 страниц V   1 2 >  
Ответить в данную темуНачать новую тему
> Аналог Q_PROPERTY
igor_bogomolov
  опции профиля:
сообщение 30.7.2009, 10:58
Сообщение #1


Профессионал
*****

Группа: Сомодератор
Сообщений: 1215
Регистрация: 22.3.2009
Из: Саратов
Пользователь №: 630

Спасибо сказали: 235 раз(а)




Репутация:   29  


Пытаюсь реализовать аналог Q_PROPERTY.

Раскрывающийся текст
class base {
public:
    typedef bool(*sp)(int);
    typedef int(*gp)();
    typedef std::pair<sp, gp> prop;
    typedef std::map<std::string, prop> PropertyMap;

public:
    base() {}
    virtual ~base() {}

public:
    bool setProperty(const char* name, int value) {
        std::string str(name);
        PropertyMap::const_iterator i = propMap.find(str);
        ((i->second).first)(value);
        return true;
    }

    int property(const char* name) const {
        std::string str(name);
        PropertyMap::const_iterator i = propMap.find(str);
        return ((i->second).second)();
    }

protected:
    PropertyMap propMap;
    bool register_property(const char* name, sp setprop, gp getprop) {
        return propMap.insert(std::make_pair(std::string(name), prop(setprop, getprop))).second;
    }
};


class base1 : public base
{
public:
    base1() {
        //register_property("TEST",&base1::setTestProp, &base1::getTestProp()); //< ??? Проблема здесь
    }

    bool setTestProp(int val) {
        return true;
    }

    int getTestProp() {
        return 125;
    }
};


Весь затык в том, что в базовый класс надо передать указатели на не статические методы классов потомков.
Как можно решить эту проблему?

Можно конечно для каждого метода делать,что-то вроде
static int call_getTestProp(base1& param) {
     return param.getTestProp();
}
и передавать указатель уже этого метода
Но тогда весь смысл в свойствах теряется.
Как быть?


Кто-нибудб делал что-то подобное. Может есть другой способ реализации PROPERTY?

Сообщение отредактировал igor_bogomolov - 30.7.2009, 11:02
Перейти в начало страницы
 
Быстрая цитата+Цитировать сообщение
BRE
  опции профиля:
сообщение 30.7.2009, 11:41
Сообщение #2


Профессионал
*****

Группа: Участник
Сообщений: 1112
Регистрация: 6.3.2009
Из: Ростов-на-Дону
Пользователь №: 591

Спасибо сказали: 264 раз(а)




Репутация:   44  


Посмотри на boost::bind.
Перейти в начало страницы
 
Быстрая цитата+Цитировать сообщение
igor_bogomolov
  опции профиля:
сообщение 30.7.2009, 11:54
Сообщение #3


Профессионал
*****

Группа: Сомодератор
Сообщений: 1215
Регистрация: 22.3.2009
Из: Саратов
Пользователь №: 630

Спасибо сказали: 235 раз(а)




Репутация:   29  


Цитата(BRE @ 30.7.2009, 12:41) *
Посмотри на boost::bind
Все утро на него смотрю и на boost::ref, boost::mem_fn, boost::function.
Ничего не получается. Не могу разобраться. Только начал разбираться с boost. Сложен он для меня (((

register_property("TEST",boost::bind(&base1::setTestProp), boost::bind(&base1::getTestProp));

Выдает кучу ошибок. Не пойму как переделать надо?
Поможите, а? )))
Перейти в начало страницы
 
Быстрая цитата+Цитировать сообщение
BRE
  опции профиля:
сообщение 30.7.2009, 12:01
Сообщение #4


Профессионал
*****

Группа: Участник
Сообщений: 1112
Регистрация: 6.3.2009
Из: Ростов-на-Дону
Пользователь №: 591

Спасибо сказали: 264 раз(а)




Репутация:   44  


Цитата(igor_bogomolov @ 30.7.2009, 12:54) *
Ничего не получается. Не могу разобраться. Только начал разбираться с boost. Сложен он для меня (((

register_property("TEST",boost::bind(&base1::setTestProp), boost::bind(&base1::getTestProp));

Выдает кучу ошибок. Не пойму как переделать надо?
Поможите, а? )))

Попробуй так:
register_property( "TEST", boost::bind( &base1::setTestProp, this ), boost::bind( &base1::getTestProp, this ) );
Перейти в начало страницы
 
Быстрая цитата+Цитировать сообщение
igor_bogomolov
  опции профиля:
сообщение 30.7.2009, 12:13
Сообщение #5


Профессионал
*****

Группа: Сомодератор
Сообщений: 1215
Регистрация: 22.3.2009
Из: Саратов
Пользователь №: 630

Спасибо сказали: 235 раз(а)




Репутация:   29  


Выдает следущую ошибку
main.cpp:80: error: no matching function for call to ‘base1::register_property(const char [5], boost::_bi::bind_t<bool (&)(int), boost::_mfi::dm<bool ()(int), base1>, boost::_bi::list1<boost::_bi::value<base1*> > >, boost::_bi::bind_t<int, boost::_mfi::mf0<int, base1>, boost::_bi::list1<boost::_bi::value<base1*> > >)’
main.cpp:67: note: candidates are: bool base::register_property(const char*, bool (*)(int), int (*)())
Перейти в начало страницы
 
Быстрая цитата+Цитировать сообщение
Влад
  опции профиля:
сообщение 30.7.2009, 12:16
Сообщение #6


Участник
**

Группа: Участник
Сообщений: 146
Регистрация: 20.3.2009
Из: Санкт-Петербург
Пользователь №: 627

Спасибо сказали: 46 раз(а)




Репутация:   8  


Посмотри, например, вот на это: http://www.progz.ru/forum/index.php?showtopic=27073&st=0
Перейти в начало страницы
 
Быстрая цитата+Цитировать сообщение
BRE
  опции профиля:
сообщение 30.7.2009, 12:20
Сообщение #7


Профессионал
*****

Группа: Участник
Сообщений: 1112
Регистрация: 6.3.2009
Из: Ростов-на-Дону
Пользователь №: 591

Спасибо сказали: 264 раз(а)




Репутация:   44  


Набросаю прямо здесь небольшой пример:
typedef boost::function<bool (int)> SetFunc;
typedef boost::function<int ()> GetFunc;

bool register_property(const char* name, SetFunc setprop, GetFunc getprop)
{
    ...
}
Перейти в начало страницы
 
Быстрая цитата+Цитировать сообщение
igor_bogomolov
  опции профиля:
сообщение 30.7.2009, 13:33
Сообщение #8


Профессионал
*****

Группа: Сомодератор
Сообщений: 1215
Регистрация: 22.3.2009
Из: Саратов
Пользователь №: 630

Спасибо сказали: 235 раз(а)




Репутация:   29  


cpp
class base
{
public:
    base();
    virtual ~base();

    typedef function<bool (int)> SetFunc;
    typedef function<int ()> GetFunc;
    typedef pair<SetFunc, GetFunc> Set_Get_Pair;
    typedef map<string, Set_Get_Pair> PropertyMap;

    bool setProperty(const char* name, int value) {
        std::string str(name);
        PropertyMap::const_iterator i = propMap.find(str);
        ((i->second).first)(value);
        return true;
    }

    int property(const char* name) const {
        string str(name);
        PropertyMap::const_iterator i = propMap.find(str);
        return ((i->second).second)();
    }

protected:
    PropertyMap propMap;
    bool register_property(const char* name, SetFunc setprop, GetFunc getprop) {
        return propMap.insert(make_pair(string(name), Set_Get_Pair(setprop, getprop))).second;
    }
};


class device : public base
{
public:
    device() {
    SetFunc sf = bind(&device::setTestProp, this); // ошибка!!!!!
//    GetFunc gf = bind(&device::getTestProp);
//    register_property("Test", sf, gf);
    }

    bool setTestProp(int /*val*/) {
        return true;
    }

    int getTestProp() {
        return 125;
    }
};
вывод
Цитата
/usr/include/boost/bind/mem_fn.hpp: In member function ‘R& boost::_mfi::Dm<R, T>::operator()(T*) const [with R = bool ()(int), T = device]’:
/usr/include/boost/bind/bind.hpp:236: instantiated from ‘R boost::_bi::list1<A1>::operator()(boost::_bi::type<R>, F&, A&, long int) [with R = bool (&)(int), F = boost::_mfi::Dm<bool ()(int), device>, A = boost::_bi::list1<int&>, A1 = boost::_bi::value<device*>]’
/usr/include/boost/bind/bind_template.hpp:32: instantiated from ‘typename boost::_bi::result_traits<R, F>::type boost::_bi::bind_t<R, F, L>::operator()(A1&) [with A1 = int, R = bool (&)(int), F = boost::_mfi::Dm<bool ()(int), device>, L = boost::_bi::list1<boost::_bi::value<device*> >]’
/usr/include/boost/function/function_template.hpp:131: instantiated from ‘static R boost::detail::function::function_obj_invoker1<FunctionObj, R, T0>::invoke(boost::detail::function::function_buffer&, T0) [with FunctionObj = boost::_bi::bind_t<bool (&)(int), boost::_mfi::Dm<bool ()(int), device>, boost::_bi::list1<boost::_bi::value<device*> > >, R = bool, T0 = int]’
/usr/include/boost/function/function_template.hpp:904: instantiated from ‘void boost::function1<R, T1>::assign_to(Functor) [with Functor = boost::_bi::bind_t<bool (&)(int), boost::_mfi::Dm<bool ()(int), device>, boost::_bi::list1<boost::_bi::value<device*> > >, R = bool, T0 = int]’
/usr/include/boost/function/function_template.hpp:720: instantiated from ‘boost::function1<R, T1>::function1(Functor, typename boost::enable_if_c<boost::type_traits::ice_not::value, int>::type) [with Functor = boost::_bi::bind_t<bool (&)(int), boost::_mfi::Dm<bool ()(int), device>, boost::_bi::list1<boost::_bi::value<device*> > >, R = bool, T0 = int]’
/usr/include/boost/function/function_template.hpp:1040: instantiated from ‘boost::function<R ()(T0)>::function(Functor, typename boost::enable_if_c<boost::type_traits::ice_not::value, int>::type) [with Functor = boost::_bi::bind_t<bool (&)(int), boost::_mfi::Dm<bool ()(int), device>, boost::_bi::list1<boost::_bi::value<device*> > >, R = bool, T0 = int]’
main.cpp:129: instantiated from here
/usr/include/boost/bind/mem_fn.hpp:342: error: invalid use of non-static member function


Что я опять делаю не так ???
Перейти в начало страницы
 
Быстрая цитата+Цитировать сообщение
BRE
  опции профиля:
сообщение 30.7.2009, 13:50
Сообщение #9


Профессионал
*****

Группа: Участник
Сообщений: 1112
Регистрация: 6.3.2009
Из: Ростов-на-Дону
Пользователь №: 591

Спасибо сказали: 264 раз(а)




Репутация:   44  


Более подробный рабочий пример:
Раскрывающийся текст

#include <boost/function.hpp>
#include <boost/bind.hpp>
#include <iostream>

class Base
{
public:
    typedef boost::function<bool (int)> SetFunc;
    typedef boost::function<int ()> GetFunc;

    Base() : m_value( 0 ) {}

    bool set( int val )
    {
    std::cout << "set=" << val << std::endl;
    m_value = val;
    return true;
    }

    int get()
    {
    return m_value;
    }

private:
    int    m_value;
};

int main( int, char ** )
{
    Base b;

    Base::SetFunc sf = boost::bind( &Base::set, &b, _1 );
    Base::GetFunc gf = boost::bind( &Base::get, &b );

    std::cout << "get=" << gf() << std::endl;
    sf( 100 );
    std::cout << "get=" << gf() << std::endl;
    
    return 0;
}

Перейти в начало страницы
 
Быстрая цитата+Цитировать сообщение
igor_bogomolov
  опции профиля:
сообщение 30.7.2009, 14:12
Сообщение #10


Профессионал
*****

Группа: Сомодератор
Сообщений: 1215
Регистрация: 22.3.2009
Из: Саратов
Пользователь №: 630

Спасибо сказали: 235 раз(а)




Репутация:   29  


BRE, спасибо огромнейшее. Все получилось. :rolleyes:

Осталось отвязаться от конкретных типов. Пока не понял что лучше использовать - boost::any или boost::variant ?

Как обобщу, выложу готовый пример. Может еще кому пригодится :)


ЗЫ. Тему лучше перенести в boost.
Перейти в начало страницы
 
Быстрая цитата+Цитировать сообщение

2 страниц V   1 2 >
Быстрый ответОтветить в данную темуНачать новую тему
Теги
Нет тегов для показа


2 чел. читают эту тему (гостей: 2, скрытых пользователей: 0)
Пользователей: 0




RSS Текстовая версия Сейчас: 27.11.2024, 4:27