其他一些不使用 std::function 的想法,它使用 std::set 并且您为要执行的每个操作创建一个类。想法是动作类是在使用它们的类的 cpp 文件中定义的(不是在头文件中,除非它们是共享的),它们是完全隐藏的。
首先定义Action类,它有一个纯虚拟执行、一个优先级和一个指向某个所有者的指针。这个想法是不创建其他类、元组,而是使用Action类来存储这些值:
class Action
{
public:
Action(const int priority, void * owner) : priority(priority), owner(owner) {}
virtual ~Action() {}
virtual void execute() = 0;
struct PrioritySorter
{
bool operator()(Action* a, Action* b)
{
return a->priority < b->priority;
}
};
bool ownerIs(void * owner) const { return this->owner == owner; }
private:
const int priority;
void * owner;
};
然后创建一些动作:
class DrawBackgroundAction : public Action
{
public:
DrawBackgroundAction(const int priority, void * owner) : Action(priority, owner) {}
void execute()
{
cout << "drawing background" << endl;
}
};
class DrawForegroundAction : public Action
{
public:
DrawForegroundAction(const int priority, void * owner) : Action(priority, owner) {}
void execute()
{
cout << "drawing foreground!!!" << endl;
}
};
class DrawSomethingElseAction : public Action
{
public:
DrawSomethingElseAction(const int priority, void * owner) : Action(priority, owner) {}
void execute()
{
cout << "drawing something else" << endl;
}
};
DrawManager负责将动作存储在按优先级排序的集合中,如果要删除“拥有的”动作(其他类),您可以这样做。
class DrawManager
{
public:
DrawManager() {}
~DrawManager()
{
for ( ActionList::iterator i = actions.begin(), e = actions.end(); i != e; i++ )
{
delete *i;
}
actions.clear();
}
void draw()
{
for ( ActionList::iterator i = actions.begin(), e = actions.end(); i != e; i++ )
{
(*i)->execute();
}
}
void addAction(Action* action)
{
actions.insert(action);
}
void removeOwnedActions(void * owner)
{
for ( ActionList::iterator i = actions.begin(), e = actions.end(); i != e; i++)
{
if ( (*i)->ownerIs(owner) )
{
delete *i;
actions.erase(i);
}
}
}
private:
typedef std::set<Action*,Action::PrioritySorter> ActionList;
ActionList actions;
};
现在示例类:
class Example
{
public:
Example()
{
manager.addAction(new DrawForegroundAction(100,this));
manager.addAction(new DrawBackgroundAction(0,this));
manager.addAction(new DrawSomethingElseAction(50,this));
}
void drawAll()
{
manager.draw();
}
void removeTheActionsIfYouWant()
{
manager.removeOwnedActions(this);
}
private:
DrawManager manager;
};
和测试:
int main()
{
Example ex;
cout << "Drawing all" << endl;
ex.drawAll();
ex.removeTheActionsIfYouWant();
cout << "Drawing again" << endl;
ex.drawAll();
return 0;
}