2009-03-23 31 views
5

Hãy xem xét một mã sau:Có thể tạo bộ điều phối cuộc gọi phương thức trong C++ không?

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"); 
} 

Câu hỏi là cách triển khai Người điều phối. Tôi không quan tâm X và Y có thể kế thừa từ một cái gì đó, nhưng Dispatcher nên cho phép khách hàng hơn nữa (không chỉ X và Y). Và tôi muốn tránh con trỏ void nếu có thể :)

+0

bạn có quyền truy cập vào thư viện tăng không? –

+0

Bạn có thể vui lòng làm rõ "Vấn đề là loại cấu trúc dữ liệu giữ con trỏ phương pháp hoặc functors." –

+0

Tôi đã cố gắng để thực hiện điều này với std :: tr1 :: mem_fun mẫu. Nhưng loại kết quả có bên trong loại tham số. Vì vậy, tôi không thể tạo ra một vectơ không đồng nhất có chứa nó. –

Trả lời

5

Hãy xem boost::function, thực hiện việc này.

+0

Tôi không giải quyết được sự cố. Hãy xem câu hỏi được cập nhật. –

+0

Có thể. Tôi đang điều tra :) –

1

Tôi có câu trả lời tương tự here, nhưng câu trả lời của Mykola gần hơn với những gì bạn cần.

1

Hãy xem bài viết này:

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

Nó thực hiện một mẫu dựa functor trong C++. void * được sử dụng dưới các mũ trùm đầu, nhưng tất cả đều an toàn vì nó được bao bọc bởi các hàm mẫu tạo và bỏ trống void *. Nó sẽ làm cho việc thực hiện điều này trở nên dễ dàng. Nó hỗ trợ nhiều kiểu gọi khác nhau mà các con trỏ phương thức không (ví dụ bạn có thể truyền một hàm trả về một cái gì đó như là một hàm trả về functor và nó tự động bỏ qua giá trị trả lại)

2

Để tránh tăng cường sử dụng và thực hiện của riêng bạn, bạn có thể hãy xem cuốn sách http://en.wikipedia.org/wiki/Modern_C%2B%2B_Design

Có thư viện Loki được mô tả trong sách với giải thích tốt về cách làm đủ thông minh cho người cần thư của bạn.

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

Điều này có vẻ tuyệt vời. Làm thế nào để nó cast typeof (& X :: MethodX) vào FunctionT? Làm cách nào để tự triển khai và tránh tăng mức sử dụng? –

+0

Để tránh tăng cường sử dụng ... và sau đó bạn đang sử dụng boost :: function? –

Các vấn đề liên quan