2009-03-23 17 views
5

Aşağıdaki kodu göz önünde bulundurun:C++ yöntem çağrı dağıtıcısı oluşturmak mümkün mü?

struct X { 
    void MethodX() { 
    ... 
    } 
}; 

struct Y { 
    void MethodY() { 
    ... 
    } 
}; 

void test() { 
    X x; 
    Y y; 
    Dispatcher d; 
    d.Register("x", x, &X::MethodX); 
    d.Register("y", y, &Y::MethodY); 
    d.Call("x"); 
    d.Call("y"); 
} 

Soru, Dağıtımcının nasıl uygulanacağıdır. X ve Y'nin bir şeyden miras alabileceğini düşünmüyorum, fakat Dispatcher daha fazla istemciye izin vermelidir (sadece X ve Y değil). Ve mümkünse void * işaretçilerden kaçınmak istiyorum :)

+0

Yükseltme kitaplığına erişiminiz var mı? –

+0

"Sorun, yöntem işaretleyicilerini veya functor'ları koruyan veri yapısının türüdür." –

+0

Bunu std :: tr1 :: mem_fun şablonuyla uygulamaya çalışıyorum. Ancak sonucun tipi parametrelerin türünde vardı. Bu yüzden onu içeren heterojen bir vektör yapamadım. –

cevap

5

boost::function'a bakın, bunu yapar.

+0

Sorunu çözmüyorum. Güncellenen soruya bir göz atın. –

+0

Belki de öyle. Araştırıyorum :) –

1

Benzer bir yanıtım var here, ancak Mykola'nın yanıtı ihtiyacınız olana daha yakın.

1

Bu yazıda bir göz atın: O C++ bir şablon tabanlı functor uygulayan

http://www.oopweb.com/CPP/Documents/FunctionPointers/Volume/CCPP/functor/functor.html

. void * başlıkların altında kullanılır, ancak hepsi güvenlidir, çünkü void * 'i yaratan ve açan şablon işlevleriyle sarılır. Bunu kolaylaştıracaktı. Bu, düz yöntem işaretçilerinin yapamayacağı çeşitli çağrı stillerini destekler (örneğin, bir dönüşü geçersiz kılan bir işlev döndüren bir işlevi iletebilir ve otomatik olarak geri dönüş değerini yoksayar)

2

Takviyeyi önlemek ve kendi uygulamanızı uygulamak için kitabın http://en.wikipedia.org/wiki/Modern_C%2B%2B_Design

nasıl iyi bir açıklama ile kitapta anlatılan bir Loki kütüphane mevcuttur bakmak senin senin ihtiyaç funktor için yeterince zeki kendi.

class Dispather 
{ 
public: 
    typedef boost::function< void (void) > FunctionT; 

    void Register(const std::string& name, FunctionT function) 
    { 
     registered_[ name ] = function; 
    } 

    void Call(const std::string& name) 
    { 
     RegisterdFunctionsT::const_iterator it = 
      registered_.find(name); 

     if (it == registered_.end()) 
      throw std::logic_error("Function is not registered"); 

     (it->second)(); 
    } 

private: 
    typedef std::map< std::string, FunctionT > RegisterdFunctionsT; 
    RegisterdFunctionsT registered_; 

}; 

int main() 
{ 
    X x; 
    Y y; 

    Dispather d; 
    d.Register("x", boost::bind(&X::MethodX, &x)); 
    d.Register("y", boost::bind(&Y::MethodY, &y)); 

    d.Call("x"); 
    d.Call("y"); 

    return 0; 
} 
+0

Bu harika görünüyor. Tipo (& X :: MethodX) nasıl FunctionT içine dökülür? Bunu kendim nasıl uygulayabilirim ve kullanımı nasıl artırabilirim? –

+0

Takviye kullanımını önlemek için ... ve sonra boost :: function kullanıyorsunuz? –