Những gì tôi có cho đến nay là:Sử dụng weak_ptr để thực hiện mô hình Observer
Observer.h
class Observer
{
public:
~Observer();
virtual void Notify() = 0;
protected:
Observer();
};
class Observable
{
public:
~Observable();
void Subscribe(std::shared_ptr<Observer> observer);
void Unsubscribe(std::shared_ptr<Observer> observer);
void Notify();
protected:
Observable();
private:
std::vector<std::weak_ptr<Observer>> observers;
};
Observer.cpp
void Observable::Subscribe(std::shared_ptr<Observer> observer)
{
observers.push_back(observer);
}
void Observable::Unsubscribe(std::shared_ptr<Observer> observer)
{
???
}
void Observable::Notify()
{
for (auto wptr : observers)
{
if (!wptr.expired())
{
auto observer = wptr.lock();
observer->Notify();
}
}
}
(de/nhà thầu được thực hiện ở đây nhưng có sản phẩm nào , vì vậy tôi đã bỏ chúng ra)
Điều tôi đang gặp phải là cách triển khai thủ tục Hủy đăng ký. Tôi đi qua xóa - loại bỏ thành ngữ, nhưng tôi hiểu rằng nó sẽ không làm việc "ra khỏi hộp" với cách tôi đã thiết lập quan sát của tôi. Làm thế nào để kiểm tra các yếu tố weak_ptr trong vector quan sát sao cho tôi có thể loại bỏ Trình quan sát mong muốn?
Tôi cũng đang tìm một số lời khuyên về loại tham số nên dành cho các thủ tục Bỏ đăng ký của tôi. Sẽ tốt hơn nếu sử dụng std::shared_ptr<Observer>&
hoặc const std::shared_ptr<Observer>&
, vì chúng tôi sẽ không sửa đổi nó? Tôi thực sự không muốn có Observables sở hữu các quan sát viên của họ, vì nó có vẻ phản bội ý định của mô hình, và chắc chắn không phải là cách tôi muốn cấu trúc phần còn lại của dự án mà cuối cùng sẽ sử dụng mẫu . Điều đó nói rằng, một lớp bảo mật/tự động hóa bổ sung mà tôi đang xem xét là để các nhà quan sát lưu trữ một véc-tơ gương của weak_ptr. Một Observer trên đường ra sau đó có thể hủy đăng ký khỏi tất cả các Observables mà nó đã đăng ký, và một Observable trên đường đi có thể xóa bỏ tham chiếu ngược về chính nó từ mỗi Quan sát viên quan sát nó. Rõ ràng hai lớp sẽ là bạn trong một kịch bản như vậy.
Lưu ý rằng 'std :: remove_if' không ** không ** xóa các phần tử khỏi vùng chứa. Bạn phải sử dụng 'container.erase' cùng với nó. Tìm kiếm thành phần xóa-xóa. – Nawaz
... mặc dù trong trường hợp này, 'std :: remove_if' sẽ là (có thể) không hiệu quả; 'std :: find_if' cùng với' .erase' sẽ hoạt động tốt hơn (hoặc ít nhất * ngữ nghĩa * chính xác). – Nawaz
Đã thêm wptr.expired() kiểm tra an toàn và xóa các quan sát viên đã chết. – M2tM