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

Поиск:

Ответ в темуСоздание новой темы Создание опроса
> Как передать метод объекта в функцию? 
:(
    Опции темы
tararataka
Дата 9.9.2010, 11:13 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Новичок



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

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



Ну и собственно, как?  smile  Я разобрался как передавать функции и объекты. А метод объекта в функцию не влазит.  smile 
PM MAIL   Вверх
djamshud
Дата 9.9.2010, 11:22 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Пердупержденный
***


Профиль
Группа: Завсегдатай
Сообщений: 1655
Регистрация: 23.11.2009

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



Код

void foo(void(Class::*ptr)(int,double));


Как-то так.


--------------------
'Cuz I never walk away from what I know is right
Alice Cooper - Freedom
PM   Вверх
azesmcar
Дата 9.9.2010, 11:23 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


uploading...
****


Профиль
Группа: Участник Клуба
Сообщений: 6291
Регистрация: 12.11.2004
Где: Армения

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



Код

class X
{
public:
    void foo()
    {
        std::cout << "X::foo()" << std::endl;
    }
};

typedef void (X::*method)();

void call(X* ptr, method xm)
{
    (ptr->*xm)();
}

int main() 
{
    X x;
    method m = &X::foo;
    call(&x, m);
}

речь об этом?
PM   Вверх
tararataka
Дата 9.9.2010, 13:09 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Новичок



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

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



djamshud azesmcar
Ага, спасибо, это оно самое.

То есть мне нужно передать и адрес на объект и на метод класса, а потом "соединить" их.

А я могу делать это как-то более универсально, ну что-бы проделывать это с объектами разных классов? Или это единственный путь?
PM MAIL   Вверх
mrbrooks
Дата 9.9.2010, 13:18 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


трололомен
****


Профиль
Группа: Завсегдатай
Сообщений: 4259
Регистрация: 4.10.2006
Где: Дол Гулдур

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



tararataka, здесь на мой взгляд самый кошерный ФАК по твоему вопросу. 
PM MAIL   Вверх
azesmcar
Дата 9.9.2010, 13:22 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


uploading...
****


Профиль
Группа: Участник Клуба
Сообщений: 6291
Регистрация: 12.11.2004
Где: Армения

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



Цитата(tararataka @  9.9.2010,  13:09 Найти цитируемый пост)
А я могу делать это как-то более универсально, ну что-бы проделывать это с объектами разных классов? Или это единственный путь? 

можно подробнее?
PM   Вверх
djamshud
Дата 9.9.2010, 13:26 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Пердупержденный
***


Профиль
Группа: Завсегдатай
Сообщений: 1655
Регистрация: 23.11.2009

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



tararataka, указатель на член класса А не получится использовать с объектом класса В, если только они не находятся в родственных связях. Если вы об этом.


--------------------
'Cuz I never walk away from what I know is right
Alice Cooper - Freedom
PM   Вверх
tararataka
Дата 9.9.2010, 14:47 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Новичок



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

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



Кстати. Вот ещё подробный туториал. Я по нему разбираюсь.
http://www.newty.de/fpt/index.html

azesmcar
Цитата
можно подробнее?

Эээээ. Ну для сумрачного плана.

djamshud
Цитата
указатель на член класса А не получится использовать с объектом класса В, если только они не находятся в родственных связях. Если вы об этом.

Тогда шаблоны?

Это сообщение отредактировал(а) tararataka - 9.9.2010, 14:48
PM MAIL   Вверх
tararataka
Дата 9.9.2010, 16:45 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Новичок



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

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



Так вот шаблон.
Код

template<typename TO> // TO - Type Object
void tdeleg(TO *pt2Object, void (TO::*p2method)()) {
    (pt2Object->*p2method)();
}


Он позволяет этой функции работать с любыми классами.
Код

tdeleg(&any,&Any::tails);

Но всё равно это неудобно. Нужно давать адрес объекта, затем ещё адрес функции класса. Нельзя это как-нибудь тоже оптимизировать? Что бы я указал только метод any.tails , а препроцессор бы превратил это в нужное выражение?
PM MAIL   Вверх
Леопольд
Дата 9.9.2010, 20:17 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Опытный
**


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

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



tararataka, если метод не статический, то ему в аргументах передаётся указатель на интанс класса, который известен под именем this.


--------------------
вопросов больше чем ответов
PM MAIL   Вверх
Cheloveck
Дата 9.9.2010, 21:03 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Эксперт
***


Профиль
Группа: Завсегдатай
Сообщений: 1578
Регистрация: 26.7.2008
Где: Тула

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



А ведь об этом написано почти во всех книгах. Вы пробовали почитать?
user posted image


--------------------
user posted image
PM Jabber   Вверх
tararataka
Дата 10.9.2010, 09:06 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Новичок



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

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



Леопольд
Цитата

tararataka, если метод не статический, то ему в аргументах передаётся указатель на интанс класса, который известен под именем this. 

 smile 

С использованием этого указателя можно переписать шаблон так, что бы передавать внутрь только что то вроде &any.tails ? 

Код

template<typename TO> // TO - Type Object
void tdeleg(TO *pt2Object, void (TO::*p2method)()) {
    (pt2Object->*p2method)();
}

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


Эксперт
***


Профиль
Группа: Завсегдатай
Сообщений: 1578
Регистрация: 26.7.2008
Где: Тула

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



tararataka, у каждого объекта класса свой набор данных. Статические методы принадлежат классу, а не объекту. Таким образом из статического метода нельзя работать с не статическими данными объекта (собственно объекта не будет). ТО, что вы хотите - невозможно, в принципе. Ещё раз настоятельно рекомендую прочитать учебник по C++. Там всё написано.


--------------------
user posted image
PM Jabber   Вверх
tararataka
Дата 10.9.2010, 09:35 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Новичок



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

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



Цитата

ТО, что вы хотите - невозможно, в принципе.

Это снимает вопрос. Но вот в куте же это реализовано. Или это они там через свой moc нашаманили?  smile 

Cheloveck
Цитата
Ещё раз настоятельно рекомендую прочитать учебник по C++.

Ну ты бы название что-ли сказал. А ту книжку что я читал, так там про эти Function Pointers, Callbacks and Functors ничего нет. Ну кроме упоминания предикатов в в стл.

Это сообщение отредактировал(а) tararataka - 10.9.2010, 09:36
PM MAIL   Вверх
Cheloveck
Дата 10.9.2010, 10:01 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Эксперт
***


Профиль
Группа: Завсегдатай
Сообщений: 1578
Регистрация: 26.7.2008
Где: Тула

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



Цитата(tararataka @  10.9.2010,  09:35 Найти цитируемый пост)
там через свой moc нашаманили?

Да, в куте не совсем C++.


Цитата(tararataka @  10.9.2010,  09:35 Найти цитируемый пост)
Ну ты бы название что-ли сказал.

Бьерн Страуструп - Язык программирования C++


--------------------
user posted image
PM Jabber   Вверх
djamshud
Дата 10.9.2010, 10:41 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Пердупержденный
***


Профиль
Группа: Завсегдатай
Сообщений: 1655
Регистрация: 23.11.2009

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



tararataka, что именно вы хотите скопировать из куте? Я не совсем понимаю. Покажите пример использования. Ибо moc отвечает только за обработку signals: и slots:, все остальное - обычный С++.


--------------------
'Cuz I never walk away from what I know is right
Alice Cooper - Freedom
PM   Вверх
tararataka
Дата 10.9.2010, 11:14 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Новичок



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

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



djamshud 
Собственно я это и имел ввиду. Cвязывание двух функций. smile

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

Это сообщение отредактировал(а) tararataka - 10.9.2010, 11:15
PM MAIL   Вверх
djamshud
Дата 10.9.2010, 11:23 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Пердупержденный
***


Профиль
Группа: Завсегдатай
Сообщений: 1655
Регистрация: 23.11.2009

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



tararataka, что - это? сама функция connect moc-ом не обрабатывается. Точнее, это макрос.

Добавлено через 1 минуту и 6 секунд
То есть вы хотите сделть свои сигналы/слоты, правильно? То есть систему посыла сообщений в программе, да?


--------------------
'Cuz I never walk away from what I know is right
Alice Cooper - Freedom
PM   Вверх
xvr
Дата 10.9.2010, 11:59 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Эксперт
****


Профиль
Группа: Комодератор
Сообщений: 7046
Регистрация: 28.8.2007
Где: Дублин, Ирландия

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



Цитата(tararataka @  9.9.2010,  13:09 Найти цитируемый пост)
А я могу делать это как-то более универсально,

Насколько я понимаю вам нужен __closure указатель. С++ напрямую не поддерживает. Поддерживается как расширение языка в Borland C++ Builder (или как оно сейчас называется)
Не уверен, что его можно вообще реализовать в С++ с ТЕМ ЖЕ синтаксисом, что и в BCB

PM MAIL   Вверх
tararataka
Дата 10.9.2010, 12:45 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Новичок



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

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



djamshud
Код
То есть вы хотите сделть свои сигналы/слоты, правильно? То есть систему посыла сообщений в программе, да?

Ага. Только я так понимаю лучше этим не заморачиваться. )
PM MAIL   Вверх
djamshud
Дата 10.9.2010, 12:58 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Пердупержденный
***


Профиль
Группа: Завсегдатай
Сообщений: 1655
Регистрация: 23.11.2009

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



tararataka, ну почему. Я ради интереса делал это когда-то. На самом деле все очень просто. Но можно взять иготовые из Qt, boost или еще какой-нибудь библиотеки. Если на выходных в инет вылезу, выложу свою реализацию. Или в понеделник.


--------------------
'Cuz I never walk away from what I know is right
Alice Cooper - Freedom
PM   Вверх
tararataka
Дата 10.9.2010, 14:01 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Новичок



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

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



djamshud
Цитата
Если на выходных в инет вылезу, выложу свою реализацию. Или в понеделник.

Давай, интересно будет посмотреть.
PM MAIL   Вверх
Master01
Дата 10.9.2010, 21:27 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Шустрый
*


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

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





посмотрите boost::bind

а вдруг это то что вы искали

PM MAIL   Вверх
djamshud
Дата 13.9.2010, 20:37 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Пердупержденный
***


Профиль
Группа: Завсегдатай
Сообщений: 1655
Регистрация: 23.11.2009

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



Во. Версия сырая и требует обработки напи^Wмакросами. Очень легко приделать регистрацию не только методов, но и обычных функций. Также может захотеться передавать что-нибудь через сигналы (в данной версии они умеют только пинать соседей). Самый простой способ - использовать какую-нибудь абстрактную структуру или набор variant-ов. Полноценно передача параметров делается через огромные костыли с помощью шаблонов (см реализацию сигналов в boost) или с помощью препроцесора (см Qt).

Код

#include<stdint.h>
#include<string.h>
#include<stdio.h>

#include<vector>

// #include<stLogger.h>
#define stDebug(...) fprintf(stderr,"%s: ",__PRETTY_FUNCTION__); fprintf(stderr,__VA_ARGS__);fprintf(stderr,"\n")


class signaler {
protected:
    class caller_iface;
    template<typename T>class caller;
    struct sig_t;
    typedef uint8_t member_t[sizeof(void*)*8];//buf for member pointer. buf is so large for stupid compilers like MSVC
    typedef std::vector<caller_iface*> dst_t;

    std::vector<sig_t> sigs;

    template<typename T>
    dst_t* __findSignal(void(T::*)());

public:

    template<typename T>
    void __registerSignal(void(T::*)());

    template<typename Tsrc,typename Tdst>
    void __addSlot(void(Tsrc::*)(),Tdst*,void(Tdst::*)());

    template<typename T>
    void __emit(void(T::*)());

};

struct signaler::sig_t {
    member_t fnc;
    dst_t dst;
};

class signaler::caller_iface {
public:
// virtual bool compare(caller_iface*)=0; //I'll need it when I want remove slots (aka disconnect)
    virtual void call()=0;
};


template<typename T>
class signaler::caller:public signaler::caller_iface {
protected:
    T *obj;
    void(T::*fnc)();
public:
    caller(T*,void(T::*)());
    void call();
};

template<typename T>
signaler::caller<T>::caller(T *_obj,void(T::*_fnc)()):obj(_obj),fnc(_fnc) {
}

template<typename T>
void signaler::caller<T>::call() {
    (this->obj->*this->fnc)();
}


template<typename T>
signaler::dst_t* signaler::__findSignal(void(T::*fnc)()) {
    for (int i=0;i<this->sigs.size();i++)
        if (memcmp(&fnc,this->sigs[i].fnc,sizeof(fnc))==0)
            return &this->sigs[i].dst;
    return 0;
}

template<typename T>
void signaler::__registerSignal(void(T::*fnc)()) {
    if (this->__findSignal(fnc)!=0) {
        stDebug("signal is already registred.");
        return;
    }
    struct sig_t sig;
    memset(sig.fnc,0,sizeof(sig,fnc));
    memcpy(sig.fnc,&fnc,sizeof(fnc));
    this->sigs.push_back(sig);
}

template<typename Tsrc,typename Tdst>
void signaler::__addSlot(void(Tsrc::*s_fnc)(),Tdst *d_obj,void(Tdst::*d_fnc)()) {
    dst_t *vct=this->__findSignal(s_fnc);
    if (vct==0) {
        stDebug("can not find signal.");
        return;
    }
    vct->push_back(new caller<Tdst>(d_obj,d_fnc));
}

template<typename T>
void signaler::__emit(void(T::*fnc)()) {
    dst_t *vct=this->__findSignal(fnc);
    if (vct==0) {
        stDebug("can not find signal.");
        return;
    }
    for (int i=0;i<vct->size();i++)
        vct->at(i)->call();
}





class test1:public signaler {
public:
    void sig1() {}
    void sig2() {}
};

class test2 {
public:
    char const *str;
    test2(char const *str) {
        this->str=str;
    }
    void slot1() {
        stDebug("%s",str);
    }
};


int main() {
    test1 t1;

    test2 t21("Hello");
    test2 t22("world");

    t1.__registerSignal(&test1::sig1);
    t1.__addSlot(&test1::sig1,&t21,&test2::slot1);
    t1.__addSlot(&test1::sig1,&t22,&test2::slot1);


    t1.__emit(&test1::sig1);

    return 0;
}




--------------------
'Cuz I never walk away from what I know is right
Alice Cooper - Freedom
PM   Вверх
Страницы: (2) [Все] 1 2 
Ответ в темуСоздание новой темы Создание опроса
Правила форума "С++:Общие вопросы"
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.0728 ]   [ Использовано запросов: 22 ]   [ GZIP включён ]


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

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