how to generate String difference vectors? - c++

a bit of a vague question but I am looking for pointers as to how can I generate String diff vectors in C++. The scenario is such that given a paragraph I want to store the various differences(Edit, cut copy paste etc.) it goes through in a draft mode to review Audit history.
Any hints in this regard will be really appreciated.

An idea using C++ polymorphism:
class Action
{
public:
virtual void revert(std::string& base) = 0;
};
class InsertAction : public Action
{
private:
int pos, len;
public:
InsertAction(int pos, std::string& base, const std::string& in) : len(in.size()), pos(pos)
{
base.insert(pos, in);
}
virtual void revert(std::string& base)
{
base.erase(pos,len);
}
};
int main()
{
std::string text("hello !");
std::cout << text << std::endl;
Action* action = new InsertAction(5, text, " world");
std::cout << text << std::endl;
action->revert(text);
std::cout << text << std::endl;
delete action;
}
You can then add and pop Actions from a LIFO queue as you want. It's a simple example, you could also try to link it more to a string instead of always passing at as a param, but that's up to your own design. I know it's not 'real' diffing, but I think this solution to be closer coupled to the problem then really storing general string differences.

Related

How can I maintain a good data encapsulation in this situation?

I am new in c++, I am trying to make a very simple CRUD program.
In this example, a client bought many things in a store, and this store has the information about the things that this client bought. I called it Inventory.
The store, wants to print a Report for every client. In the code below, the main just has one Inventory, just for sample.
The problem is: When I want to print the Report, I have to get the data from the client, but without lose encapsulation. I mean, I want that no class can modify the content of the inventory.
What I am trying to do is convert the map into a vector (I need something to sort the data) and pass this vector (dinamically allocated).
I am allocating this vector at the class Inventory but who is deleting
is the class Report, this is not the correctly way to do things, but I do not know how to pass this information without doing like this.
Anyway, the report class can get the pointer to a Book, and use its set function or point to other Book. Again, I do not know how to do it correctly.
Can someone give me a tip what I have to do in this case ?
Thanks.
Sorry for the long code.
Main:
int main(void)
{
Inventory i;
Report r(i);
i.addBook("Foo Bar I");
i.addBook("Foo Bar II");
r.generateReport();
return 0;
}
Class Report in .h:
class Report
{
private:
Inventory* i;
public:
Report(Inventory& i);
void generateReport();
};
Class Report in cpp:
Report::Report(Inventory& i)
{
this->i = &i;
}
void Report::generateReport()
{
ofstream out ("Report.txt");
out << "Books: " << endl;
vector<pair<int, Book *>> * b = i->getBooks();
for(pair<int, Book *> p : *b)
{
out << p.first << ": " << p.second.getName() << endl;
}
out << endl;
delete b;
out.close();
}
Class Inventory in .h:
class Inventory
{
private:
map<int, Book *> books;
public:
void addBook(int code, const string& name);
vector<pair<int, Book *>> * getBooks();
};
Class Inventory in .cpp:
void Inventory::addBook(int code, const string& name)
{
books.insert(pair<int, Book *>(code, new Book(name)));
}
vector<pair<int, Book *>> * Inventory::getBooks()
{
return new vector<pair<int, Book *>>(books.begin(), books.end());
}
Your inventory class should have this interface:
class Inventory
{
private:
map<int, Book *> books;
public:
using const_iterator = std::map<int, Book*>::const_iterator;
void addBook(int code, const string& name);
const_iterator begin() const { return books.begin(); }
const_iterator end() const { return books.end(); }
};
no reason to create a copy of the map into a vector! that is inefficient and not reason for doing it.
Rewrite the generateReport to work with this interface as follows:
for(const auto &p : *i)
{
out << p.first << ": " << p.second.getName() << endl;
}
out << endl;
With your approach, the trick to transform the map into a vector introductes only an additional dependency: the report has to know about the internals of the inventory.
I'd rather recommend to go the way of the vistitor design pattern: the goal is to separate the algorithm (producing the report, the visitor) from the datastructure you explore (the inventory and its items).
class Item { ...}; // Your object structure
class Book : public Item { ... };
class Inventory { ...};
class Visitor { ... }; // Algorithms that shall be executed on structure
class Report : public Visitor {...};
This could also simplify the implementation of your inventory, as you'd no longer need to foresee different containers for different kind of items (provided they all inherit from some common element base class).
Theres is plenty of litterature on this pattern. I recommend you Design patterns, elements of reusable object oriented software from Gamma & al: its the orginal textbook, and guess what, the demo code shows an inventory with a pricing visitor ;-)
Here a naive on-line example based on your problem, to illustrate how it could work.

Using C-like API in OOP

I am writing some classes in C++ to act as a personal small library and I encountered a problem.
Some of my objects make us of third-party libraries written in magnificent C style.
That means those libraries have functions like apiInit() and apiCleanup(), where the former must be called before any of the actual api functions and the latter must be called when you are not going to use them anymore.
What I want is to provide the classes that need a library with an access point to its functions ensuring apiInit() is called when the first needing class is created, or at least before any api function is used, and apiCleanup() is called when the last instance that uses the api is destroyed.
Keep in mind there are more than one class that makes use of a single library.
I could come with two solutions:
First, the obvious one, make the provider a singleton:
#include <iostream>
using namespace std;
class ContextProvider {
ContextProvider() {
cout << "Initializing API" << endl;
}
ContextProvider(ContextProvider const& rhs) = delete;
ContextProvider& operator=(ContextProvider const& rhs) = delete;
public:
~ContextProvider() {
cout << "Cleaning API" << endl;
}
static ContextProvider& getInstance() {
static ContextProvider instance;
return instance;
}
void useContext() {
cout << "Using API" << endl;
}
};
class ContextUser1 {
public:
ContextUser1() {
}
void doSomething() {
ContextProvider::getInstance().useContext();
}
};
class ContextUser2 {
public:
ContextUser2() {
}
void doSomethingElse() {
ContextProvider::getInstance().useContext();
}
};
The other one would be to keep a counter of context users, like so:
#include <iostream>
using namespace std;
class ContextProvider {
static unsigned int userCounter;
public:
ContextProvider() {
if (userCounter == 0)
cout << "Initializing API" << endl;
++userCounter;
}
~ContextProvider() {
--userCounter;
if (userCounter == 0)
cout << "Cleaning API" << endl;
}
void useContext() {
cout << "Using API" << endl;
}
};
unsigned int ContextProvider::userCounter = 0;
class ContextUser1 {
ContextProvider cp;
public:
ContextUser1() {
cp = ContextProvider();
}
void doSomething() {
cp.useContext();
}
};
class ContextUser2 {
ContextProvider cp;
public:
ContextUser2() {
cp = ContextProvider();
}
void doSomethingElse() {
cp.useContext();
}
};
int main() {
ContextUser1 cu11, cu12, cu13;
ContextUser2 cu21, cu22;
cu11.doSomething();
cu12.doSomething();
cu21.doSomethingElse();
cu22.doSomethingElse();
cu13.doSomething();
}
Both, when executed with the following main()
int main() {
ContextUser1 cu11, cu12, cu13;
ContextUser2 cu21, cu22;
cu11.doSomething();
cu12.doSomething();
cu21.doSomethingElse();
cu22.doSomethingElse();
cu13.doSomething();
}
yeld the expected result, that is:
Initializing API
Using API
Using API
Using API
Using API
Using API
Cleaning API
Now the obvious question is, which one is better, or which one should I use?
For example, some things that come to mind are...
Singleton method:
Advantages:
No need to store any counter.
No need to store any instance.
Disadvantages:
Syntaxis gets weird (ContextProvider::getInstance().use()).
It is a singleton, with all it's flaws.
Counter method:
Advantages:
The usage is straightfowrard.
The syntaxis is nice and clear (cp.use()).
Disadvantages:
Has to keep a counter of the number of users.
User classes have to store an instance of the ContextProvider class.
I mainly ask this question because I don't know which of these advantages/disadvantages weight more, if there are things I didn't account for, or maybe there is an obvious third method I couldn't come up with that is inherently better than those two, or, who knows.
Thank you for your time!
I'd use your second approach, with the following modifications:
class ContextUser1 {
std::shared_ptr<ContextProvider> cp;
public:
ContextUser1(const std::shared_ptr<ContextProvider>& cp)
: cp(cp) {
}
void doSomething() {
cp->useContext();
}
};
Making the dependency explicit makes your code better in terms of being testable. Also, using shared_ptr takes care of counting, so you don't even need to do this yourself.

Accessing variables shared between classes within an aggregator class

I have a problem in hand which requires to make a very modular design for different algorithms. For example population based optimization algorithms like genetic algorithm, particle swarm algorithm etc. There are several variants of these algorithms, therefore I planned to make the smaller building blocks as an abstract class and let the specific building block to be plugged in.
For example lets say we have algo1 which can be divided in the following subroutines
algo1
loop
{
sub1 ()
sub2 ()
sub3 ()
}
For this I can create three interfaces which the implementation will override as per their implementation. Therefore
//Sub1Class, Sub2Class, Sub3Class are interfaces/abstract classes
class algo1
{
sub1Class *sub1Obj;
sub2Class *sub2Obj;
sub3Class *sub3Obj;
}
// constructor or setter method to set the implementation
algo1 (Sub1Class *myAlgo1Obj, Sub2Class myAlgo1Obj, Sub3Class myAlgo1Obj)
{
sub1Obj = myAlgo1Obj;
sub2Obj = myAlgo2Obj;
sub3Obj = myAlgo3Obj;
}
doAlgo1
{
loop
{
sub1Obj->algo ();
sub2Obj->algo ();
sub3Obj->algo ();
}
}
This can be done, but all the algorithms uses the attributes of the algo class and there are intermediate variables shared by the algorithms which I do not want to give a getter/setter.
My question is what are the techniques which can be used to manage the shared intermediate variables between the algorithms. I can pass it as the algo method implementation argument, but the number of intermediates and the types may change from one implementation to another. In that case will it be a good idea to create a separate class of temporary variable or make something like friend in cpp? Note that the intermediate results can be large vectors and matrices.
Please let me know if you need more information or clarification.
NOTE: I can possibly omit the variables shared between the algorithms by introducing locals and re-computation, but the algorithms are iterative and computation intensive involving large matrices therefore I want to make object creation and destruction as minimum as possible.
I can propose to use Inverse of Control container to solve your problem.
First you should create several abstract classes to keep it in the container:
class ISubroutineState {
public:
ISubroutineState() = default;
virtual int getVar1() const = 0;
virtual void setVar1(int v1) = 0;
};
class ISubroutineState1 : public ISubroutineState {
public:
virtual std::string getVar2() const = 0;
virtual void setVar2(std::string& v2) = 0;
};
The example of the subroutine state class implementation:
class SubState1 : public ISubroutineState1 {
int var1;
std::string var2;
public:
int getVar1() const {
return var1;
}
std::string getVar2() const {
return var2;
}
void setVar1(int v1) { var1 = v1; }
void setVar2(std::string& v) { var2 = v; }
};
The the IoC container (please note it can be accessed in any way allowed - i used just static pointer for simplicity):
class StateBroker
{
std::map<const char*, ISubroutineState*> *storage;
public:
StateBroker();
template <class S>
void StateBroker::bind(S* state) {
storage->emplace(typeid(S).name(), state);
}
template <class S>
S* StateBroker::get() const {
auto found = storage->find(typeid(S).name());
if (found == storage->end()) return NULL;
return (S*)found->second;
}
~StateBroker();
};
StateBroker* stateBroker;
Now you can implement any type of the subroutines:
class ISubroutine {
public:
virtual void Execute() = 0;
};
class Sub1Class : public ISubroutine {
public:
void Execute()
{
if (stateBroker == NULL)
{
std::cout << "Sub1 called" << std::endl;
}
else {
ISubroutineState1* ss1 = stateBroker->get<ISubroutineState1>();
std::cout << "Sub1 with state called" << std::endl;
ss1->setVar1(1);
ss1->setVar2(std::string("State is changed by Sub1Class"));
std::cout << *static_cast<SubState1*>(ss1) << std::endl;
}
}
};
class Sub2Class : public ISubroutine {
public:
void Execute()
{
if (stateBroker == NULL)
{
std::cout << "Sub2 called" << std::endl;
}
else {
ISubroutineState* ss1 = stateBroker->get<ISubroutineState>();
std::cout << "Sub2 with state called" << std::endl;
ss1->setVar1(2);
std::cout << *static_cast<SubState1*>(ss1) << std::endl;
}
}
};
class Sub3Class : public ISubroutine {
public:
void Execute()
{
if (stateBroker == NULL)
{
std::cout << "Sub3 called" << std::endl;
}
else {
ISubroutineState1* ss1 = stateBroker->get<ISubroutineState1>();
std::cout << "Sub3 with state called" << std::endl;
ss1->setVar1(3);
ss1->setVar2(std::string("State is changed by Sub3Class"));
std::cout << *static_cast<SubState1*>(ss1) << std::endl;
}
}
};
Also please note that subroutine' Execute() can request any type of subroutine state it requires to perform their tasks. It can even create additional state instances (to use in later stage of the algorithm, for example).
Now the main algorithm would look like this:
class Algo {
private:
Sub1Class* sub1;
Sub2Class* sub2;
Sub3Class* sub3;
public:
Algo(Sub1Class* s1, Sub2Class* s2, Sub3Class* s3) : sub1(s1), sub2(s2), sub3(s3){}
void Execute()
{
sub1->Execute();
sub2->Execute();
sub3->Execute();
}
};
... and it's usage (please note it can be used as stateless and as statefull depending on the fact the StateBroker is initialized or not)
Sub1Class s1;
Sub2Class s2;
Sub3Class s3;
std::cout << "Stateless algorithm" << std::endl;
Algo mainAlgo(&s1, &s2, &s3);
mainAlgo.Execute();
stateBroker = new StateBroker();
SubState1* state = new SubState1();
stateBroker->bind<ISubroutineState>(state);
stateBroker->bind<ISubroutineState1>(state);
std::cout << "Statefull algorithm" << std::endl;
Algo statefulAlgo(&s1, &s2, &s3);
statefulAlgo.Execute();
Please note that Algo class doesn't know anything about subroutine states, state broker, etc.; Sub2Class doesn't know about ISubroutineState1; and StateBroker doesn't care about state and subroutine implementation.
BTW, you can review the example project at https://github.com/ohnefuenfter/cppRestudy (VS2015)

Overwriting virtual functions in body of code

I have a question about virtual functions in C++. I have spent the last hour searching but I'm getting nowhere quickly and I was hoping that you could help.
I have a class that handles transmitting and receiving data. I would like the class to be as modular as possible and as such I would like to make an abstract/virtual method to handle the received messages.
Although I know I could create a new class and overwrite the virtual method, I don't really want to have to create a large array of new classes all implementing the method different ways. In Java you can use listeners and/or override abstract methods in the body of the code when declaring the object as can be seen in the example.
JTextField comp = new JTextField();
comp.addActionListener(new ActionListener() {
public void actionPerformed(ActionEvent evt) {
//Handler Code
}
});
Is this possible in C++ or is there a better approach to this sort of problem?
Cheers and Many thanks in advance,
Chris.
Have look at this other SO post Does C++0x Support Anonymous Inner Classes as the question sounds similar.
Functors (function objects) or lambdas could be suitable alternatives.
In C++, you need to declare a new class:
class MyActionListener: public ActionListener
{
public:
void actionPerformed(ActionEvent evt) { ... code goes here ... }
};
The question has already been answered but I thought I'd throw this in for good measure. The SO discussion linked in the example is good but concentrates mostly on replicating the Java experience. Here's a more idiomatic C++ way of doing it:
struct EventArgs
{
int param1;
int param2;
};
class network_io
{
typedef std::function<void (EventArgs)> Event;
typedef std::vector<Event> EventList;
EventList Events;
public:
void AddEventHandler(Event evt)
{
Events.push_back(evt);
}
void Process()
{
int i,j;
i = j = 1;
std::for_each(std::begin(Events), std::end(Events), [&](Event& e)
{
EventArgs args;
args.param1 = ++i;
args.param2 = j++;
e(args);
});
}
};
int main()
{
network_io ni;
ni.AddEventHandler([](EventArgs& e)
{
std::cout << "Param1: " << e.param1 << " Param2: " << e.param2 << "\n";
});
ni.AddEventHandler([](EventArgs& e)
{
std::cout << "The Param1: " << e.param1 << " The Param2: " << e.param2 << "\n";
});
ni.Process();
}

Is there an idiomatic way to create a collection of delegates in C++?

I want to store functions with similar signature in a collection to do something like this:
f(vector<Order>& orders, vector<Function>& functions) {
foreach(process_orders in functions) process_orders(orders);
}
I thought of function pointers:
void GiveCoolOrdersToBob(Order);
void GiveStupidOrdersToJohn(Order);
typedef void (*Function)(Order);
vector<Function> functions;
functions.push_back(&GiveStupidOrdersToJohn);
functions.push_back(&GiveCoolOrdersToBob);
Or polymorphic function objects:
struct IOrderFunction {
virtual void operator()(Order) = 0;
}
struct GiveCoolOrdersToBob : IOrderFunction {
...
}
struct GiveStupidOrdersToJohn : IOrderFunction {
...
}
vector<IOrderFunction*> functions;
functions.push_back(new GiveStupidOrdersToJohn());
functions.push_back(new GiveCoolOrdersToBob());
Premise:
The design you propose will work, but using regular function pointers will limit you considerably in the kind of callbacks you can register, and although more powerful, the approach based on inheritance from a fixed interface is more verbose and requires more work for a client to define callbacks.
In this answer I will first show some examples of how to use std::function for this purpose. The examples will pretty much speak for themselves, showing how and why using std::function brings advantages as opposed to the kind of solutions you outlined.
However, a naive approach based on std::function will also have limitations of its own, which I am going to list. This is why I eventually suggest you to have a look at Boost.Signals2: it is a pretty powerful and easy-to-use library. I will address Boost.Signals2 at the end of this answer. Hopefully, understanding a simple design based on std::function first will make it easier for you to grasp the more complex aspects of signals and slots later on.
Solution based on std::function<>
Let's introduce a couple of simple classes and prepare the ground for some concrete examples. Here, an order is something which has an id and contains several items. Each item is described by a type (for simplicity, here it can be either a book a dvd), and a name:
#include <vector>
#include <memory>
#include <string>
struct item // A very simple data structure for modeling order items
{
enum type { book, dvd };
item(type t, std::string const& s) : itemType(t), name(s) { }
type itemType; // The type of the item
std::string name; // The name of the item
};
struct order // An order has an ID and contains a certain number of items
{
order(int id) : id(id) { }
int get_id() const { return id; }
std::vector<item> const& get_items() const { return items; }
void add_item(item::type t, std::string const& n)
{ items.emplace_back(t, n); }
private:
int id;
std::vector<item> items;
};
The heart of the solution I am going to outline is the following class order_repository, and its internal usage of std::function to hold callbacks registered by clients.
Callbacks can be registered through the register_callback() function, and (quite intuitively) unregistered through the unregister_callback() function by providing the cookie returned by registered_callback() upon registration:
The function than has a place_order() function for placing orders, and a process_order() function that triggers the processing of all orders. This will cause all of the registered handlers to be invoked sequentially. Each handler receives a reference to the same vector of placed orders:
#include <functional>
using order_ptr = std::shared_ptr<order>; // Just a useful type alias
class order_repository // Collects orders and registers processing callbacks
{
public:
typedef std::function<void(std::vector<order_ptr>&)> order_callback;
template<typename F>
size_t register_callback(F&& f)
{ return callbacks.push_back(std::forward<F>(f)); }
void place_order(order_ptr o)
{ orders.push_back(o); }
void process_all_orders()
{ for (auto const& cb : callbacks) { cb(orders); } }
private:
std::vector<order_callback> callbacks;
std::vector<order_ptr> orders;
};
The strength of this solution comes from the use of std::function to realize type erasure and allow encapsulating any kind of callable object.
The following helper function, which we will use to generate and place some orders, completes the set up (it simply creates four orders and adds a few items to each order):
void generate_and_place_orders(order_repository& r)
{
order_ptr o = std::make_shared<order>(42);
o->add_item(item::book, "TC++PL, 4th Edition");
r.place_order(o);
o = std::make_shared<order>(1729);
o->add_item(item::book, "TC++PL, 4th Edition");
o->add_item(item::book, "C++ Concurrency in Action");
r.place_order(o);
o = std::make_shared<order>(24);
o->add_item(item::dvd, "2001: A Space Odyssey");
r.place_order(o);
o = std::make_shared<order>(9271);
o->add_item(item::dvd, "The Big Lebowski");
o->add_item(item::book, "C++ Concurrency in Action");
o->add_item(item::book, "TC++PL, 4th Edition");
r.place_order(o);
}
Now let's see what kinds of callback we can provide. For starter, let's have a regular callback function that prints all of the orders:
void print_all_orders(std::vector<order_ptr>& orders)
{
std::cout << "Printing all the orders:\n=========================\n";
for (auto const& o : orders)
{
std::cout << "\torder #" << o->get_id() << ": " << std::endl;
int cnt = 0;
for (auto const& i : o->get_items())
{
std::cout << "\t\titem #" << ++cnt << ": ("
<< ((i.itemType == item::book) ? "book" : "dvd")
<< ", " << "\"" << i.name << "\")\n";
}
}
std::cout << "=========================\n\n";
}
And a simple program that uses it:
int main()
{
order_repository r;
generate_and_place_orders(r);
// Register a regular function as a callback...
r.register_callback(print_all_orders);
// Process the order! (Will invoke all the registered callbacks)
r.process_all_orders();
}
Here is the live example showing the output of this program.
Quite reasonably, you are not limited to registering regular functions only: any callable object can be registered as a callback, including a functor holding some state information. Let's rewrite the above function as a functor which can either print the same detailed list of orders as function print_all_orders() above, or a shorter summary that does not include order items:
struct print_all_orders
{
print_all_orders(bool detailed) : printDetails(detailed) { }
void operator () (std::vector<order_ptr>& orders)
{
std::cout << "Printing all the orders:\n=========================\n";
for (auto const& o : orders)
{
std::cout << "\torder #" << o->get_id();
if (printDetails)
{
std::cout << ": " << std::endl;
int cnt = 0;
for (auto const& i : o->get_items())
{
std::cout << "\t\titem #" << ++cnt << ": ("
<< ((i.itemType == item::book) ? "book" : "dvd")
<< ", " << "\"" << i.name << "\")\n";
}
}
else { std::cout << std::endl; }
}
std::cout << "=========================\n\n";
}
private:
bool printDetails;
};
Here is how this could be used in a small test program:
int main()
{
using namespace std::placeholders;
order_repository r;
generate_and_place_orders(r);
// Register one particular instance of our functor...
r.register_callback(print_all_orders(false));
// Register another instance of the same functor...
r.register_callback(print_all_orders(true));
r.process_all_orders();
}
And here is the corresponding output shown in this live example.
Thanks to the flexibility offered by std::function, we can also register the result of std::bind() as a callback. To demonstrate this with an example, let's introduce a further class person:
#include <iostream>
struct person
{
person(std::string n) : name(n) { }
void receive_order(order_ptr spOrder)
{ std::cout << name << " received order " << spOrder->get_id() << std::endl; }
private:
std::string name;
};
Class person has a member function receive_order(). Invoking receive_order() on a certain person object models the fact that a particular order has been delivered to that person.
We could use the class definition above to register a callback function that dispatches all the orders to one person (which can be determined at run-time!):
void give_all_orders_to(std::vector<order_ptr>& orders, person& p)
{
std::cout << "Dispatching orders:\n=========================\n";
for (auto const& o : orders) { p.receive_order(o); }
orders.clear();
std::cout << "=========================\n\n";
}
At this point we could write the following program, that register two callbacks: the same function for printing orders we have used before, and the above function for dispatching orders to a certain instance of Person. Here is how we do it:
int main()
{
using namespace std::placeholders;
order_repository r;
generate_and_place_orders(r);
person alice("alice");
r.register_callback(print_all_orders);
// Register the result of binding a function's argument...
r.register_callback(std::bind(give_all_orders_to, _1, std::ref(alice)));
r.process_all_orders();
}
The output of this program is shown in this live example.
And of course one could use lambdas as callbacks. The following program builds on the previous ones to demonstrate the usage of a lambda callback that dispatches small orders to one person, and large orders to another person:
int main()
{
order_repository r;
generate_and_place_orders(r);
person alice("alice");
person bob("bob");
r.register_callback(print_all_orders);
r.register_callback([&] (std::vector<order_ptr>& orders)
{
for (auto const& o : orders)
{
if (o->get_items().size() < 2) { bob.receive_order(o); }
else { alice.receive_order(o); }
}
orders.clear();
});
r.process_all_orders();
}
Once again, this live example shows the corresponding output.
Beyond std::function<> (Boost.Signals2)
The above design is relatively simple, quite flexible, and easy to use. However, there are many things it does not allow to do:
it does not allow to easily freeze and resume the dispatching of events to a particular callback;
it does not encapsulate sets of related callbacks into an event
class;
it does not allow grouping callbacks and ordering them;
it does not allow callbacks to return values;
it does not allow combining those return values.
All these feature, together with many others, are provided by full-fledged libraries such as Boost.Signals2, which you may want to have a look at. Being familiar with the above design, it will be easier for you to understand how it works.
For instance, this is how you define a signal and register two simple callbacks, and call them both by invoking the signal's call operator (from the linked documentation page):
struct Hello
{
void operator()() const
{
std::cout << "Hello";
}
};
struct World
{
void operator()() const
{
std::cout << ", World!" << std::endl;
}
};
int main()
{
boost::signals2::signal<void ()> sig;
sig.connect(Hello());
sig.connect(World());
sig();
}
As usual, here is a live example for the above program.
You might want to look into std::function, your vector would then look like this:
std::vector< std::function< void( Order ) > > functions;
But be aware that std::function has a small overhead. For the instances, drop the new:
function.push_back(GiveStupidOrdersToJohn());
Boost.Signal solves exactly your problem. You should have a look into that. Unless you have special requirements. In particular boost.signal and boost.function and/or std::function
use type erasure techniques. Thus, you are able to have a vector of callable things with a specified signature. It does not matter if your entities are plain C-functions (as you have in your example) or function-objects or member-functions in general. You can mix all of them.