A map of boost:signals with boost:function definition - c++

I am trying to create a simple manager that will map error codes to functions. But since a map copies the values and a signal is noncopyable that is not a solution. I cannot use a map of shared_ptr pointers since the * operator is blocked in boost::function.
Which collection should I use to store this?
typedef boost::function<bool (shared_ptr<EngineEvent> event,long timeSinceEvent)> EngineErrorHandler;
typedef boost::signal<bool ( EngineErrorHandler )> ErrorSignal;
typedef std::map<EventErrorType,ErrorSignal> ErrorHandlers;
class ServiceErrorManager {
public:
static ServiceErrorManager* getInstance();
void registerErrorHandler(EngineErrorHandler& handler,EventErrorType subScribeTo);
void signalEngineEventfail(shared_ptr<EngineEvent> event);
private:
static ServiceErrorManager* m_pInstance;
ErrorHandlers errorTypeToSignal;
ServiceErrorManager();
~ServiceErrorManager();
};
}

You could always store everything into a struct and store shared_ptr or unique_ptr objects inside a map or set using a custom predicate. This seems like it would make your code a bit more self-explanatory as well.

Related

Is there a good way to combine or simplify these STL maps?

I'm writing a class that needs to store a bunch of different primitives and classes. I've decided to make a map for each different data type where the key in the map would be the name of the variable, and the value in the map would be the value of the variable. My maps are defined like this:
std::unordered_map<std::string, int> myInts;
std::unordered_map<std::string, float> myFloats;
std::unordered_map<std::string, Something> mySomethings;
For each map, I have to write two methods, one which will get the value of some variable and one which will set the value of some variable like so:
void setMyInt(const std::string &varName, int newVal) {
myInts[varName] = newVal;
}
int getMyInt(const std::string &varName) {
return myInts[varName];
}
This is all fine and easy, however, I ended up with 8 different maps, and 16 of these get set methods. This doesn't seem very efficient or clean to me, not to mention that every time I need to store a new data type I have to define a new map and write 2 new get-set methods.
I considered getting rid of the get set methods and instead writing 2 template methods which would take in the type of the variable which the user needs to get or set, and then accessing the proper set to perform the operation, like so:
template<class Type>
void getVariable<Type>(const std::string &varName) {
// if Type == int -> return myInts[varName];
// else if Type == float -> return myFloats[varName];
}
This seems like a really poor approach since the user could pass in types which are not supported by the class, and the method breaks C++'s rule of not being really generic.
Another idea I had was writing some Variable class which would have all of the fields that this class should store, along with some enum that defines what Variable the class is actually being used for, and then making a map of this Variable class like this:
enum Type {
TYPE_INT,
TYPE_FLOAT,
TYPE_SOMETHING
class Variable {
Type type;
int myInt;
float myFloat;
Something mySomething;
}
std::unordered_map<std::string, Variable> myVariables;
But this also seems like a really poor solution, or at least one which is difficult to understand. Is there some smart way to make this class store different types?
How about a template class like below:
template<typename ValueType>
class UnorderedStringMap : public std::unordered_map<std::string, ValueType> {
public:
...
void setValue(const std::string &varName, ValueType newVal) {
std::unordered_map::operator[](varName) = newVal;
}
const ValueType& getValue(const std::string &varName) {
return std::unordered_map::operator[](varName);
}
...
}
UnorderedStringMap<int> myInts;
UnorderedStringMap<float> myFloats;
You can then use it as a normal std::unordered_map as well.

C++ what is proper way to include STL container in my class?

To begin with, I'm new to C++/OOP.
I want to include a std::map in my class and am wondering about how to provide users of my class the map typedefs and capabilities. Do I need to do as in the simple example below? (I've only shown a subset to indicate what I'm trying to do)
It doesn't feel right that I have to do this for any class where I've included a container (even for a subset of map methods).
It also seems like a class maintenance issue (e.g. might not need some map method today, but it becomes needed in the future)
p.s. aside from replying to this question, any other corrections/feedback to the example below are appreciated.
#include <map>
#include <string>
class Inventory {
public:
typedef std::string key_type;
typedef std::string mapped_type;
typedef std::map<key_type, mapped_type>::value_type value_type;
Inventory() { }
Inventory(int lotNum) : lotNum_(lotNum) { }
void insert(const value_type& el) { cars_.insert(el); }
//
// TODO: iterators, erase, etc
//
private:
int lotNum_;
std::map<key_type, mapped_type> cars_;
};
int main() {
Inventory ourCars(1);
ourCars.insert( Inventory::value_type( "BMW","ABC123" ) );
return 0;
}
Here is how I would think about this problem. Think of your class interface and implementation separately. The user shouldn't need to know what you're doing behind the scenes - what containers you're using etc. Your class itself should have some functionality that you provide through its interface. I'm not sure what your class is supposed to do, but if you want a function to insert two strings you should just provide that function. That's your starting point. Then you decide that you're going to store your strings in a map or whatever. In summary, the types that go into the map will be decided by your class interface. What you're doing is the opposite - deciding how you're implementing it and then exposing the types of your map in the interface.

Map to method c++11

I'm tried to make a map to class methods using C++11's function.
The C-Style function pointers:
Method:
void MyClass::MyMethod(void*);
Map declare:
std::map<int, void (MyClass::*)(void*)> mapIdToMethod;
Map insert:
mapIdToMethod.insert(std::make_pair(2, &MyClass::MyMethod));
Method call:
MyClass mc;
(mc.*mapIdToMethod.at(1))(nullptr);
The code above is worked, But how can I convert it to use C++11's function?
What i'm tried:
Map declare:
std::map<int, function<void(void*)>> mapIdToMethod;//The map declare
Now, how can I insert and call the method on this map?
Probably not as efficient as the original but maybe easier to read:
std::map<int, std::function<void (MyClass&,void*)>> mapIdToMethod;
mapIdToMethod.emplace(2, [](MyClass& c,void* p){ c.MyMethod(p);});
// alternatively:
using std::placeholders::_1;
using std::placeholders::_2;
mapIdToMethod.emplace(2,std::bind(&MyClass::MyMethod,_1,_2));
MyClass mc;
mapIdToMethod.at(2)(mc, nullptr);
I am also a fan of function over C-style pointers, but it's important that you recognize that the analog for void (MyClass::*)(void*) is function<void(MyClass&, void*)> not function<void(void*)>. So you could replicate what you've already have going in MapIdToMethod with:
map<int, function<void(MyClass&, void*)>> bar;
You could insert to this the same way as you inserted to MapIdToMethod (bar.insert(make_pair(2, &MyClass::MyMethod)), but you could also use mem_fn, which wouldn't have been possible to use when inserting to MapIdToMethod:
bar.insert(make_pair(2, mem_fn(&MyClass::MyMethod)));
Now, to answer your question. Given:
map<int, function<void(void*)>> foo;
You can insert member functions which take a void* and don't return anything, but only if you already have the object on which you wish to make the calls constructed. You can do that using bind:
MyClass mc;
foo.insert(make_pair(2, bind(&MyClass::MyMethod, mc, placeholders::_1)));
Live Example

Accessing a static std::set with accessors, is this wise or should I just access it directly?

This question follows on from the outcome of this one:
How to automatically maintain a list of class instances?
With reference to the previous question, I created my static list of objects static std::set< Object* > objects;
However, to avoid circular referencing between Engine and Object, I moved it out of Engine and into a separate header file. I then realised that rather than directly interacting with the list, I could use a bunch of static accessors. This way if anything is making changes to the list, I can always break on these functions.
Are there any other benefits for doing it this way? Or is this a bad way to go? I never intend to instantiate ObjectManager ever - should I be using what I believe are called 'free functions' instead to manage this std::set, with no class?
I have created a test project to keep things simple in testing this out. The Inheritor class inherits from the Object class. The code for the ObjectManager class (referenced by Main.cpp, Object and Inheritor in this case, but a very similar one would be used in my main project) is below:
ObjectManager.h:
#include <set>
class ObjectManager
{
friend class Object;
friend class Inheritor;
public:
static int ObjectCount();
static void AddObject(Object *);
static void RemoveObject(Object *);
static int InheritorCount();
static void AddInheritor(Inheritor *);
static void RemoveInheritor(Inheritor *);
static std::set<Object *>::iterator GetObjectListBegin();
static std::set<Object *>::iterator GetObjectListEnd();
static std::set<Inheritor *>::iterator GetInheritorListBegin();
static std::set<Inheritor *>::iterator GetInheritorListEnd();
private:
ObjectManager();
~ObjectManager();
};
ObjectManager.cpp:
#include "ObjectManager.h"
static std::set<Object *> objectList;
static std::set<Inheritor *> inheritorList;
ObjectManager::ObjectManager()
{
}
ObjectManager::~ObjectManager()
{
}
int ObjectManager::ObjectCount()
{
return objectList.size();
}
void ObjectManager::AddObject(Object *input)
{
objectList.insert(input);
}
void ObjectManager::RemoveObject(Object *input)
{
objectList.erase(input);
}
int ObjectManager::InheritorCount()
{
return inheritorList.size();
}
void ObjectManager::AddInheritor(Inheritor *input)
{
inheritorList.insert(input);
}
void ObjectManager::RemoveInheritor(Inheritor *input)
{
inheritorList.erase(input);
}
std::set<Object *>::iterator ObjectManager::GetObjectListBegin()
{
return objectList.begin();
}
std::set<Object *>::iterator ObjectManager::GetObjectListEnd()
{
return objectList.end();
}
std::set<Inheritor *>::iterator ObjectManager::GetInheritorListBegin()
{
return inheritorList.begin();
}
std::set<Inheritor *>::iterator ObjectManager::GetInheritorListEnd()
{
return inheritorList.end();
}
**
EDIT:
**
I have rewritten my code to remove the need for an ObjectManager.
Instead of using ObjectManager, each class I want a list of contains the static list in its source file, so Object.cpp contains static std::set<Object *> objectList; and Inheritor.cpp contains static std::set<Inheritor *> inheritorList;.
Then, each of those two classes contains a static Count() function, for getting the number of items in its respective list, GetListBegin() and GetListEnd() for getting the beginning and end of the set.
As the functions share the same name in both the base class and the derived one, Object::Count() gets the number of Object instances in its respective list, and Inheritor::Count() gets the number of Inheritor instances in its respective list.
I don't know if this is a bad way of doing this or not. Nothing can add or remove from the list outside of each respective class. My only issue is I'm not sure how to stop the static functions from being available in anything that say, inherits from Inheritor for example.
If std::set provides exactly the right interface then you can use it directly. If it doesn't (and that's usually the case: it has a very broad interface) then you should write a class or a set of functions that provide the interface you need, and implement appropriately, perhaps with std::set, perhaps with something else.
I would put this set as a private static member of Object class, which adds itself to the set in the constructor (don't forget copy constructor, if permissible). Then make a public read-only accessor to the set (return const reference).
I don't understand the meaning of your Inheritor set.
If this is a list of live objects in a game engine, I would make it a non-static member of engine class which keeps track of all its objects.

Creating a list that has to be accessed by the classes it uses C++

I need to create a global list that can be accessed and used by a group of classes that I have initialised, but those classes need to be included to create the list. Any ideas?
Example:
class Game_object
{
public:
~Game_object()
void Update();
void Render();
//Other stuff
};
class Explosion
{
Stuff
};
class Player
{
Stuff
};
All of these classes need to access the list below, that is in another header file, as well as my int main
std::list <Game_object *> Objects;
std::list <Explosion *> Explosions;
And so on.
The idea was that I could create an explosion instance in the destructor of the Game_object, and place it inside of the list. This was so I could have it rendering and updating inside of main
You mean Game_object should hold a std::list<Explosion *> and Explosion should hold a std::list<Game_object *>? It sounds like a job for forward declarations:
#include <list>
class Game_object;
class Explosion;
class Game_object
{
std::list<Explosion *> l;
};
class Explosion
{
std::list<Game_object *> l;
};
This works because your lists contain pointers, not actual objects.
Declare your lists in a header file (for example, mylists.h) like this:
#include <list>
#include <myGameClasses.h>
class Game_object;
class Explosion;
extern std::list<Game_object*> Objects;
extern std::list<Explosion*> Explosions;
// And so for other lists
Using extern will create a referencing declaration for your lists. You should then create the defining declarations in a source file (for example, mylists.cpp):
#include "mylists.h"
std::list<Game_object*> Objects;
std::list<Explosion*> Explosions;
// And so for other lists
Why should you do it like this? This is to prevent multiple declarations when including your header (mylists.h). Only one declaration will then be necessary which, in this case, in the source file (mylists.cpp).
To be able to use the lists, just include the header file.
Also, in mylists.h, there is also a need to for forward declarations of your classes:
class Game_object;
class Explosion;
This is to avoid an undeclared identifier errors.
Maybe it's no good idea to access these lists but if you need this kind of acces you can do it by many ways, the most simple by global variables:
// forward declare Game_object:
class Game_object;
// Declare lists:
typedef std::list <Game_object *> ListObjects;
typedef std::list <Explosion *> ListExplosions;
ListObjects Objects;
ListExplosions Explosions;
class Game_object
{
public:
void Update()
{
// Update Objects...
for (ListObjects::const_iterator O = Objects.begin(); O != Objects.end(); ++O)
{ ... };
// Update Explosions...
for (ListExplosions::const_iterator E = Explosions.begin(); E != Explosions.end(); ++E)
{ ... };
};
void Render()
{
// Render Objects...
for (ListObjects::const_iterator O = Objects.begin(); O != Objects.end(); ++O)
{ ... };
// Render Explosions...
for (ListExplosions::const_iterator E = Explosions.begin(); E != Explosions.end(); ++E)
{ ... };
};
//Other stuff
};
It isn't a good idea, the global variables could be troublesome, even worse with global lists that can be accessed by some other classes and alter its contents while another class try to alter the contents at the same time; but if you're not using threads it couldn't be that troublesome.
Other approach could be to create a manager. The manager must be the owner of the list and would need the methods Setters, Getters, and Deleters methods. To update the contents of the list you can pass a reference to the manager to a renderer/updater and get a reference to the list from the manager:
class ObjectManager
{
public:
typedef std::list <Game_object *> ListObjects;
void AddObject(const ObjectStuff &os)
{ ... };
const ListObjects &GetObjects()
{ return Objects; };
private:
ListObjects Objects;
}
class ExplosionManager
{
public:
typedef std::list <Explosion *> ListExplosions;
void AddExplosion(const ExplosionStuff &es);
{ ... };
const ListExplosions &GetExplosions()
{ return Explosions; };
private:
ListExplosions Explosions;
}
void Render(const ObjectManager &om)
{
// Ask ObjectManager for the object list
}
void Render(const ExplosionManager &em)
{
// Ask ExplosionManager the explosion list
}
The above code is a naive and pretty simple approximation but is only for example purposes. The advantage of the above approach is that the list is modified only by the owner object, if the list is needed out of the manager is provided in a read-only manner and if you are using threads, is pretty simple to add the locks and unlocks in the manager methods in order to avoid the modifications while the list is used.
This isn't asked but I think is worth to say: Could be a good idea to avoid storing object pointers into containers and change the store type by object instances:
std::list <Game_object *> VS std::list <Game_object>
When you're using pointers you must take care of the allocation and deallocation of the objects, if the lists are global you'll need a public Close method to deallocate all the memory managed by the pointers stored in the lists, if the list is owned by some object, you need to do the same process into the object destructor.
But, if you're storing object instances, the list destructor deallocates all the objects stored when it's lifetime ends, the code is cleaner and easier to maintain.