2012-09-21 8 views
1

Я реализовал свои обратные вызовы с интерфейсом ..метод обратного вызова, как

struct ICallback 
{ 
    virtual bool operator()() const = 0; 
}; 

и функции для добавления обратного вызова

void addCallback(const ICallback* callback) { .... } 

и использования, обратного вызова в некотором классе

class BusImplemantation{ 
public: 
    struct Foo : ICallback 
    { 
     virtual bool operator()() const { return true;} 
    }foo; 
    void OtherMethod(); 
    int OtherMember;  
}; 

Но поскольку callback является классом (не функцией/методом), я не могу получить обратный вызов для других методов и других участников. Если обратный вызов был бы не классом, а только методом, чем это было бы возможно. (Внутренний класс против метода)

Я не могу передать OtherMethod и OtherMember для обратного вызова в качестве параметров.

Есть ли лучшее решение для этого? может быть, с шаблонами?

ответ

1

Не могли бы вы сделать что-то вроде этого, вместо:

typedef std::function<bool()> CallbackFunc; 
void addCallback(const CallbackFunc callback) { .... } 

class BusImplemantation{ 
public: 
    struct Foo 
    { 
     Foo(member) : OtherMember(member) { } 

     bool operator()() const { return true; } 

     void OtherMethod(); 
     int OtherMember;  
    }foo; 
}; 

Вместо того, чтобы ваш обратный вызов интерфейса, сделать его использовать зЬй :: функцию, чтобы сделать его функциональный объект (функтор), а также любые дополнительные данные или методы, которые могут потребоваться вашим функторам, могут быть частью класса-функтора.

2

Использование std::function:

void addCallback(const std::function<bool()>) { .... } 

class BusImplemantation{ 
public: 
    bool Callback() { return true; } 
    void OtherMethod(); 
    int OtherMember;  
}; 

BusImplemantation obj; 
addCallback(std::bind(&BusImplemantation::Callback, obj)); 
+0

г ++ ехе (GCC) 4.5.2, я использую специальный компилятор для встроенных, я думаю, что эти функции bind() и function() здесь не включены. Я получаю ошибку: «function» в пространстве имен «std» не называет тип. – Meloun

+0

@Meloun вы включили ''? – ecatmur

+0

Да, я думаю, что это в библиотеке boost. – Meloun

0

Я думаю, что ваш интерфейс ICallback должен иметь указатель контролируемого класса с базовым интерфейсом, предположит, что BusImplemantation и внутри обратного вызова использовать этот указатель.

struct ICallback 
{ 
    virtual bool operator()() const = 0; 
    void setControlObject(BusImplemantation* o) 
    { 
    obj = o; 
    } 
    BusImplemantation* obj; 
}; 

class BusImplemantation 
{ 
public: 
    void addCallback(const ICallback* callback) 
    { 
     callback->setControlObject(this); 
    } 
    void OtherMethod(); 
    int OtherMember;  
}; 

И использование:

class SomeCb : ICallback 
{ 
    bool operator() 
    { 
     obj->OtherMethod(); 
     return true; 
    } 
} 
+0

Это не очень хорошо для меня, у меня больше классов с обратными вызовами = > BusImplemantation1, BusImplemantation2, ... Я не могу применить setControlObject к определенному классу. – Meloun

1

Весь смысл использования обратного вызова объектов вместо свободных функций является то, что вы можете связать произвольное состояние с ними:.

class BusImplemantation{ 
public: 
    struct Foo : ICallback 
    { 
     explicit Foo(BusImplementation &p) : parent(p) {} 
     virtual bool operator()() const; 

    private: 
     BusImplementation &parent; 
    } foo; 

    BusImplementation() : foo(*this) 
    { 
     addCallback(&foo) 
    } 

    void OtherMethod(); 
    int OtherMember;  
}; 

bool BusImplementation::Foo::operator()() const 
{ 
    if (parent.OtherMember == 0) { 
     parent.OtherMethod(); 
     return false; 
    } 
    return true; 
} 
Смежные вопросы