使像订阅系统С++ *字符事件
问题描述:
因此,对于像整数或常量像这样简单的数据将工作使像订阅系统С++ *字符事件
#include <iostream>
#include <vector>
using namespace std ;
typedef void FuncInt (int) ;
class GraphElementProto {
public:
void add (FuncInt* f)
{
FuncVec.push_back (f) ;
} ;
void call()
{
for (size_t i = 0 ; i < FuncVec.size() ; i++)
FuncVec[i] (i) ;
} ;
private:
vector<FuncInt*> FuncVec ;
} ;
static void f0 (int i) { cout << "f0(" << i << ")" << endl ; }
static void f1 (int i) { cout << "f1(" << i << ")" << endl ; }
int main() {
GraphElementProto a ;
a.add (f0) ;
a.add (f1) ;
a.call() ;
}
所以现在想象我们与像烧焦了一些数据缓冲区工作。
我们有等待数据指针的线程,并且该指针的外观需要同时更改数据。所以我们需要创建该数据的副本,并将每个订阅者指针指向他自己的副本。
那么如何做这样的事情呢? (对不起,C++ nube - 代码只是我能理解的东西)
答
考虑你描述的图形的每个节点之间的相似之处并为它们创建一个类(下面的GraphElement类)。它应该将其与其子节点的关系封装起来,并且应该在本地对任何传入消息执行一些操作(函数localAction)。然后,您应该派生代表特定变体的类 - 例如您提到的图像生成器 - 并更改本地操作。每个班级可能会收到原始邮件的副本,或者根据需要更改它。
在我的示例代码中,我创建了默认图形节点 - GraphNode - 并将其传递到其子节点之前,简单地打印传入的消息。我为传入消息使用了一个字符串对象 - 比普通的旧C char *数组好得多[例如:当在下面的代码中创建message2时,您可以从char *派生一个字符串]。我将这些对象的const引用作为廉价,快速,永不改变原来的。
我已经派生出一个名为CatNode的类作为您需要的变体的示例。这种类型的对象包含所有消息的历史记录,并在新消息到达时打印出历史记录。不是很有用 - 但是一个很好的例子。这将演示每个节点如何对原始消息的副本执行任何操作 - 重写localAction()。它还将该历史记录传递给任何子节点 - 通过更改传递给deliverMessage()的参数来重写incomingMessage。
#include <vector>
#include <iostream>
#include <string>
using std::cout;
using std::endl;
using std::vector;
using std::string;
class GraphNode
{
public:
GraphNode(string & name) : mChildren(), mName(name) {}
GraphNode(const char * const name) : mChildren(), mName(name==NULL?"":name) {}
virtual void incomingMessage(const string & str) {
localAction(str); // This node is to do something.
deliverMessage(str); // Child nodes are to do things too.
}
void addChild(GraphNode * child) {
mChildren.push_back(child);
}
protected:
// Rewrite this function for child classes who are to do different things with messages.
virtual void localAction(const string & str) {
cout << mName << " : " << str << endl;
}
void deliverMessage(const string & str) {
vector<GraphNode*>::iterator itr = mChildren.begin();
for(; itr != mChildren.end(); ++itr)
(*itr)->incomingMessage(str);
}
// Data members
vector<GraphNode*> mChildren;
string mName;
}; // [ GraphNode ]
class CatNode : public GraphNode
{
public:
CatNode(string & name) : GraphNode(name), mHistory() {}
CatNode(const char * const name) : GraphNode(name), mHistory() {}
virtual void incomingMessage(const string & str) {
localAction(str);
deliverMessage(mHistory);
}
protected:
virtual void localAction(const string & str) {
mHistory += str;
cout << mName << " : " << mHistory << endl;
}
// Data members
string mHistory;
}; // [ CatNode ]
main()
{
// root -> childA
GraphNode root("Root Node");
CatNode childA("Child A");
root.addChild(&childA);
root.incomingMessage("Message1");
cout << endl;
// root -> childA -> childC
// \-> childB
GraphNode childB("Child B");
root.addChild(&childB);
GraphNode childC("Child C");
childA.addChild(&childC);
string message2("Message2");
root.incomingMessage(message2);
} // [ main ]
我不是C++ nube,但我理解你的代码比你的问题好得多。请详细说明 – 2011-01-20 12:28:43
我编辑了这个问题 - 现在看起来好多了。) – Rella 2011-01-20 22:10:04