我对观察者模式有点麻烦 我有一个饮料类,使用装饰精细。 我正在尝试实现观察者,以便在这种情况下让观察者(例如手机/文本消息)知道订单何时完成。我不会包括饮料/装饰师课程,因为他们工作正常。
在主要我会做这样的事情:
Subject mySubject = new Subject();
Observer myObserver1 = new Observer1();
Observer myObserver2 = new Observer2();
// register observers
mySubject.Register(myObserver1);
mySubject.Register(myObserver2);
mySubject.Notify("message 1");
mySubject.Notify("message 2");
我有一个主题类,观察者,电话行为类和一个手机1,手机2类......
这是主题课
#ifndef _SUBJECT_
#define _SUBJECT_
//#include "Starbuzz.h"
//#include "Starbuzz2.h"
#include "Observer.h"
#include <list>
namespace CoffeeHouse {
namespace Observers {
class Subject {
private:
std::list< Observer* > observers;
public:
Subject();
~Subject();
void Subject::Register(Observer observer)
{
//if (!observers.(observer))
//{
observers.insert(observer);
}
//}
//void Unregister(Observer observer)
//{
// if observer is in the list, remove
//if (observers.Contains(observer))
//{
//observers.Remove(observer);
//}
//}
void Notify(std::string message)
{
//need loop
Observer observer;
observer.update(message);
}
//}
//}
//void Subject::registerObserver( Observer* o ) { assert( o );
//_observers.push_front(o);
//}
//void Subject::removeObserver( Observer* o ) { assert( o );
// _observers.remove(o);
//}
//void Subject::notifyObservers() const {
//for( std::list< Observer* >::iterator iterator = _observers.begin(); _observers.end() != iterator; ++iterator ) {
//Observer* observer = *iterator;
//observer->update(message);
//}
//}
};
} // namespace Observer
}
#endif
这是观察者类
#ifndef _OBSERVER_
#define _OBSERVER_
#include <string>
namespace CoffeeHouse {
namespace Observers {
class Subject;
class Observer {
//public: virtual ~Observer() = 0;
public: virtual void Update(std::string message) = 0;
};
这是手机行为类
#ifndef _PHONEBEHAVIOR_
#define _PHONEBEHAVIOR_
namespace CoffeeHouse {
namespace Observer {
class PhoneBehavior {
public: virtual void Update() const = 0;
};
protected: virtual ~PhoneBehavior() = 0 {
};
};
} // namespace Observer
} //
这是手机1
#ifndef _CELLPHONE1_
#define _CELLPHONE1_
namespace CoffeeHouse {
namespace Observer {
include<iostream>
class CellPhone1: public Observer, public PhoneBehavior {
public:
CellPhone1();
~CellPhone1();
virtual void Update(std::string message)
{
std::cout << "CellPhone1: " << message;
}
};
} // namespace Observer
} //
#endif
这里是我得到的错误..
error C2259: 'CoffeeHouse::Observers::Observer' : cannot instantiate abstract class
1> due to following members:
1> 'void CoffeeHouse::Observers::Observer::update(std::string)' : is abstract
see declaration of 'CoffeeHouse::Observers::Observer::update'
error C2661: 'std::list<_Ty>::insert' : no overloaded function takes 1 arguments
with[_Ty=CoffeeHouse::Observers::Observer *
error C2259: 'CoffeeHouse::Observers::Observer' : cannot instantiate abstract class
due to following members:
'void CoffeeHouse::Observers::Observer::update(std::string)' : is abstract
observer.h(15) : see declaration of 'CoffeeHouse::Observers::Observer::update
当我点击错误“无法实例化抽象类”时,我需要:
void Subject::Register(Observer observer)
据我所知,抽象类的制作使得它们无法实例化!
我怎么能做更新呢?有什么更好的建议吗?
我感谢任何帮助!
答案 0 :(得分:1)
我看到的问题:
Observer
和CellPhone1类源文件。#include <string>
或使用
void
Update(string message)
virtual void update()
应该有
可能有一个资本“U”留下来
符合您的编码风格和
因为这就是它的名字
CellPhone1类源文件。Cout <<"CellPhone1:" + message);
。它应该是std::cout << "CellPhone1: " << message;
#include <iostream>
class PhoneBehavior
的左大括号对应的右括号后面应该有分号。编辑:当我说“类源文件”时,我假设您的项目设置为CellPhone1.cpp,PhoneBehavior.cpp文件基于您提出问题的方式。
答案 1 :(得分:1)
一个错误是Subject :: Register当前正在使用Observer对象,而不是指向Observer的指针。这意味着您正在尝试实例化一个抽象对象,这是非法的。
答案 2 :(得分:0)
您可以通过此操作使一切可见:
https://simmesimme.github.io/tutorials/2015/09/20/signal-slot
#ifndef SIGNAL_H
#define SIGNAL_H
#include <functional>
#include <map>
//! A signal object may call multiple slots with the same
//! signature. You can connect functions to the signal which will be
//! called when the emit() method on the signal object is invoked. Any
//! argument passed to emit() will be passed to the given functions.
template <typename... Args>
class signal
{
public:
//! Default constructor.
signal(): m_slots(), m_current_id(0) {}
//! Copy constructor. (deleted)
signal(signal const& other) = delete;
//! Assignment operator. (deleted)
signal& operator=(signal const& other) = delete;
//! Connects a member function to this signal.
//!
//! @code{.cpp}
//! signal<> s;
//! int id = s.connect_member(&myclass, MyClass::method);
//! @endcode
//!
//! @param[in] instance Pointer to the instance to connect.
//! @param[in] func Pointer to the member func to connect.
//! @return id of object connected, to be used to disconnect.
template <typename T>
int connect_member(T *inst, void (T::*func)(Args...))
{
return connect([=](Args... args) {(inst->*func)(args...);});
}
//! Connects a const member function to this signal.
//!
//! @code{.cpp}
//! signal<> s;
//! int id = s.connect_member(&myclass, MyClass::method);
//! @endcode
//!
//! @param[in] instance Pointer to the instance to connect.
//! @param[in] func Pointer to the member func to connect.
//! @return id of object connected, to be used to disconnect.
template <typename T>
int connect_member(T *inst, void (T::*func)(Args...) const)
{
return connect([=](Args... args) { (inst->*func)(args...);});
}
//! Connects a std::function function wrapper to this signal.
//!
//! This method can be used to adapt many kinds of callable objects
//! to a signal.
//!
//! @code{.cpp}
//! signal<> s;
//! std::function<void()> f = std::bind(&signal_utest::test0, this);
//! int id = s.connect(f);
//! @endcode
//!
//! @param[in] slot Function object invoked on emit().
//! @return id of object connected, to be used to disconnect.
int connect(std::function<void(Args...)> const& slot) const
{
m_slots.insert(std::make_pair(++m_current_id, slot));
return m_current_id;
}
//! Disconnects a previously connected function.
//!
//! @param[in] id Id returned by connect function.
void disconnect(int id) const
{
m_slots.erase(id);
}
// Disconnects all previously connected functions.
void disconnect_all() const
{
m_slots.clear();
}
//! Calls all connected functions.
void emit(Args... p)
{
for (auto it : m_slots)
it.second(p...);
}
private:
mutable std::map<int, std::function<void(Args...)>> m_slots;
mutable int m_current_id;
};
#endif /* SIGNAL_H */
具有测试:
signal<> s0;
int id0 = -1;
UTEST_CHECK(id0 != 1);
id0 = s0.connect_member(this, &signal_utest::test0);
UTEST_CHECK(id0 == 1);
UTEST_CHECK(get_test0() == 0);
s0.emit();
UTEST_CHECK(get_test0() == 1);
signal<int> s1;
UTEST_CHECK(s1.connect_member(this, &signal_utest::test1) == 1);
UTEST_CHECK(test1() == 0);
s1.emit(1);
UTEST_CHECK(test1() == 1);
signal<int, int> s2;
UTEST_CHECK(s2.connect_member(this, &signal_utest::test2) == 1);
UTEST_CHECK(test2() == 0);
s2.emit(1, 1);
UTEST_CHECK(test2() == 2);