का उपयोग कर पर्यवेक्षक पैटर्न observer pattern से मैं एक सुरक्षित Subject
कक्षा लिखने की कोशिश कर रहा हूं। मुझे पता है कि अगर weak_ptr
का उपयोग कर सबसे अच्छा तरीका है इस तरह से IObserver
उदाहरणों स्टोर करने के लिए है चाहता हूँ कि:weak_ptr
- जाने के बाद उसे free'd कर दिया गया है एक
IObserver
उदाहरण उपयोग करने के लिए संभव नहीं है। Subject
वर्गIObserver
संदर्भ free'd किया जाना चाहिए (lapsed listener problem) पर पकड़ नहीं करता है।Subject
कक्षा धागा सुरक्षित होना चाहिए।
दुर्भाग्य से, हमारी कोडिंग मानकों का कहना है कि हम को बढ़ावा देने का उपयोग करने की अनुमति नहीं है। मुझे लगता है कि मैं पिछले जीवन में एक बुरे व्यक्ति था। सौभाग्य से, मुझे सी ++ 11 का उपयोग करने की अनुमति है (विजुअल स्टूडियो 2012 के साथ क्या भेजा जाता है)।
यहां नमूना Observer
वर्ग है।
// Observer interface that supports notify() method
class IObserver
{
public:
virtual void notify() const = 0;
virtual ~IObserver() {}
};
// Concrete observer implementation that prints a message
class Observer : public IObserver
{
public:
Observer(const std::string& message) : m_message(message){}
void notify() const {
printf("%s\r\n", m_message.c_str());
}
private:
std::string m_message;
};
और यहाँ Subject
वर्ग है।
int main(int argc, wchar_t* argv[])
{
Subject subject;
auto observerHello = std::make_shared<Observer>("Hello world");
subject.registerObserver(observerHello);
{
// Create a scope to show unregistration.
auto observerBye = std::make_shared<Observer>("Good bye");
subject.registerObserver(observerBye);
subject.doNotify();
}
printf("%s\r\n", "Observer good bye is now be destructed");
subject.doNotify();
return 0;
}
weak_ptr
धागा सुरक्षित की मेरी उपयोग है:
// Subject which registers observers and notifies them as needed.
class Subject
{
public:
// Use shared_ptr to guarantee the observer is valid right now
void registerObserver(const std::shared_ptr<IObserver>& o)
{
std::lock_guard<std::mutex> guard(m_observersMutex);
m_observers.push_back(o);
}
void unregisterObserver(const std::shared_ptr<IObserver>& o)
{
std::lock_guard<std::mutex> guard(m_observersMutex);
// Code to remove the observer from m_observersMutex
}
// This is a method that is run in its own thread that notifies observers of some event
void doNotify()
{
std::lock_guard<std::mutex> guard(m_observersMutex);
// Notify any valid observers of events.
std::for_each(m_observers.cbegin(), m_observers.cend(),
[](const std::weak_ptr<IObserver>& o)
{
auto observer = o.lock();
if (observer) {
observer->notify();
}
});
// Remove any dead observers. These are ones which have expired().
m_observers.erase(std::remove_if(m_observers.begin(), m_observers.end(),
[](const std::weak_ptr<IObserver>& o)
{
return o.expired();
}), m_observers.end());
}
private:
std::vector<std::weak_ptr<IObserver>> m_observers;
std::mutex m_observersMutex;
};
यहाँ कुछ कोड है कि Subject
अभ्यास है? यहां से https://stackoverflow.com/a/2160422/1517648 I लगता है यह है।
क्या यह लापता श्रोता समस्या को हल करने का एक वैध तरीका है?
नहीं 2012 रेंज छोरों के लिए आधारित है करता है? आप for_each का उपयोग क्यों कर रहे हैं? (प्रश्न के लिए अप्रासंगिक, हे) – David
यह सिर्फ एक आदत है, इसके अलावा इसका कोई कारण नहीं है जिसका उपयोग मैं करता हूं। – Steve