2008-10-26 39 views
19

Tôi không chắc chắn làm thế nào để tìm kiếm trực tuyến này ... Tôi nghĩ rằng họ có thể được gọi là một cái gì đó khác nhau trong C++Sự kiện trong C++

Tôi muốn có một hệ thống sự kiện đơn giản, somthing như

event myCustomEvent; 
myCustomEvent.subscribe(void myHandler(string)); 
myCustomEvent.fire("a custom argument"); 
// myHandler prints out the string passed in the first argument 


event myNewCustomEvent; 
myNewCustomEvent.subscribe(void myNewHandler(int)); 
myNewCustomEvent.fire(10); 
// myHandler prints 10 

Tôi có thể làm điều này khá dễ dàng với một lớp đơn giản - nhưng khi tôi muốn có một sự kiện vượt qua một loại khác hoặc số lượng đối số cho người đăng ký tôi phải viết và xác định một lớp sự kiện hoàn toàn mới. có phải là một số thư viện, hoặc thậm chí có thể một cái gì đó bản địa trong Visual C++ 2008 mà sẽ làm việc một cái gì đó tương tự như thế này. Đó là cơ bản chỉ là một việc thực hiện các mẫu Observer, do đó, nó không thể quá không thể làm trong C + +

Điều này thực sự làm cho tôi đánh giá cao như thế nào nó là trong JavaScript không phải lo lắng về các đối số bạn đang đi qua.

Hãy cho tôi biết nếu đây là câu hỏi ngu ngốc.

+3

Không ngu ngốc chút nào. –

Trả lời

10

Tôi sử dụng sigslot cho mục đích chính xác này.

+0

Tôi rất vui vì bạn đã nhắc tôi về điều này ... Tôi không hiểu những tín hiệu/khe là khi tôi đi qua nó (vẫn còn suy nghĩ sự kiện/thuê bao) – Robert

+3

Đây chính xác là những gì tôi đang tìm kiếm. stackoverflow là tuyệt vời. – Robert

8

Mẫu người quan sát từ GOF là khá nhiều thứ bạn muốn.

Trong cuốn sách, nó có mã C++ cho điều này ...

Ngoài ra, như mọi khi, Boost có những thứ bạn có thể tận dụng cũng

+0

Tôi đang xem cuốn sách bây giờ. Boost gọi họ là tín hiệu và khe tôi nghĩ .. và có vẻ như họ đang làm rất nhiều thứ tôi cần. Tôi có thể sẽ phải đi sâu hơn vào điều đó. – Robert

+0

Bên cạnh các tín hiệu và khe trong .NET (Visual C++), bạn có các sự kiện và đại biểu. bạn có thể đọc thêm về chúng :) – milot

+0

không thực sự là giải pháp C++ nếu bạn sử dụng .net –

19

Hãy nhìn vào việc tăng signal thư viện. Kết hợp với các thư viện functionbind, bạn có thể thực hiện chính xác những gì bạn đang tìm kiếm.

6

Có bản gốc Visual C++ event system. Đó là chủ yếu cho COM, nhưng nó có hỗ trợ C++ bản địa quá.

Từ here:

[event_source(native)] 
class CSource { 
public: 
    __event void MyEvent(int nValue); 
}; 

[event_receiver(native)] 
class CReceiver { 
public: 
    void MyHandler1(int nValue) { 
     printf_s("MyHandler1 was called with value %d.\n", nValue); 
    } 

    void MyHandler2(int nValue) { 
     printf_s("MyHandler2 was called with value %d.\n", nValue); 
    } 

    void hookEvent(CSource* pSource) { 
     __hook(&CSource::MyEvent, pSource, &CReceiver::MyHandler1); 
     __hook(&CSource::MyEvent, pSource, &CReceiver::MyHandler2); 
    } 

    void unhookEvent(CSource* pSource) { 
     __unhook(&CSource::MyEvent, pSource, &CReceiver::MyHandler1); 
     __unhook(&CSource::MyEvent, pSource, &CReceiver::MyHandler2); 
    } 
}; 

int main() { 
    CSource source; 
    CReceiver receiver; 

    receiver.hookEvent(&source); 
    __raise source.MyEvent(123); 
    receiver.unhookEvent(&source); 
} 
2

tôi sử dụng libsigc++. Nó có nguồn gốc cho gtkmm.

Một ví dụ đơn giản losely chuyển thể từ tutorial:

#include <iostream> 
#include <sigc++/sigc++.h> 

using namespace std; 

class AlienDetector { 
public: 
     void run(); 
     sigc::signal<void> signal_detected; 
}; 

void warn_people() { 
     cout << "There are aliens in the carpark!" << endl; 
} 

void AlienDetector::run() { 
     signal_detected.emit(); 
} 

int main() { 
     AlienDetector mydetector; 
     mydetector.signal_detected.connect (sigc::ptr_fun (warn_people)); 
     mydetector.run(); 
} 

Nó cũng cung cấp một cơ chế để kết nối thành viên-chức năng của các đối tượng cụ thể với các tín hiệu sử dụng sigc :: mem_fun thay vì sigc :: ptr_fun:

sigc::mem_fun (someobject, &SomeClass::some_method); 

Điều này khá nhiều cung cấp mọi thứ có thể với tín hiệu GLib.

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