I create something like a list of functors (functions pointers). Then I write them in binary form into file. The problem is, that, functor - is a simple function pointer. (correct me if I'm wrong.) But the address of function is different from one run to another.
So, the question - is there any way to create list of functors that will be relevant all the time?
I'd recommend some kind of paired data structure with an identifier on one side and the function pointer on the other. If there are enough of them something like a map:
typedef void (*fptr_t)(); // or whatever your function pointer type is
std::map<std::string, fptr_t> fptr_map;
Your application should build this map when it is first needed and cache the result. Then when you "write" the function pointers to a file, you should write the unique std::string keys instead. When the application "reads" the function pointers it will read in the keys and map them to the function pointers for that invocation of the program.
One possible solution, as #fbrereto mentions, is to label different functors with some unique identifier (integer, string, uuid, etc.), that does not depend on addresses in each particular process, and store these keys into the file. Then you can use something the Factory Design Pattern to instantiate functors on demand when reading the file.
Yes, function pointer is just an address. You can't rely on it. Instead you can create array of functors and store indexes of functors to file. or you can create hashtable and reference functors by name.
Related
Actually, I want to pass an object to function by taking input from User. There are many objects and I want user to tell which object to pass. One way that I can think of is by using if/else-if statements (e.g if user says 1(int) then it means object-1). But is there any direct method by which I can directly take object as input. So I can pass it to function without using if/else-if statements.
You cannot have a user input an object directly out-of-the-box, but you can certainly write code to obtain that result (for example by implementing deserialization and receiving a JSON representation of the object).
However, if I understood your question correctly, you have a predefined set of objects with known integer keys. In that case, the most straightforward way is to store these objects in a container, such as std::map<int, YourObject> (or an std::vector<YourObject> if your keys are easily mappable to [0;N)). Once you've had the user input the key, you can then lookup into the container to retrieve the corresponding object via the container's at() member function.
I am trying to use the following data collection in my program:
boost::unordered_set<boost::shared_ptr<Entity> > _entities;
I am using unordered_set because I want fast insertion and removal (by key, not iterator) of Entities.
My doubt is, if I implement the following two functions:
void addEntity(boost::shared_ptr<Entity> entity) {
_entities.insert(entity);
}
void removeEntity(boost::shared_ptr<Entity> entity) {
_entities.remove(entity);
}
When I try to remove the entity, will the unordered_set find it? Because the shared_ptr that is stored inside the unordered_set is a copy of the shared_ptr that I am trying to use to remove the entity from the unordered_set if I call removeEntity().
What do I need to do for the unordered_set to find the Entity? Do I need to create a comparison function that checks the values of the shared_ptr's? But then won't the unordered_set slow down because its hash function uses the shared_ptr as hash? Will I need to create a hash function that uses the Entity as hash also?
Yes you can use boost::shared_ptr in boost::unordered_set (same applies to std version of these classes)
boost::unordered_set uses boost::hash template function to generate keys for boost::unordered_set. This function is specialised for boost::shared_ptr to take underlying pointer into account.
Let me try to explain this if I got it right :-
boost::shared_ptr is implemented using reference counting mechanism. That means whenever you are passing it to some other let's say function you are just increasing reference count whereas when you delete it you are decreasing its reference count. When reference count is 0 then only that object is deleted from memory.
Always be cautious when using it. It can save you from memory leaks only as far as your design is good to accomodate them.
For example I faced one issue.
I'd a class with map containing shared_ptrs. Later this class ( without my knowledge )was also made responsible for passing these shared-ptrs to some other classes which in-turn used some containers to store these. As a result this code blowed up luckily on tester's face in the form of memory leak.
I hope you can figure out why.
What's the real benefit of using pointers to functions instead of those functions itself? Does it make execution faster ? Or does it provide convenience when it's passed to another function?
It enables you to "select" a component of your business logic around at run time -- contrast this with hardcoding the function names, which limits you to choosing which function to use at compile time.
There are situations where you must use a pointer to function, there is no other way. For example, to implement a callback function, specifying comparator function(the last parameter in sorting routines).
EDIT: As specified in the comment, this is about C. Function pointer came from C.
Function pointers are how you store functions in variables and pass them into other functions. There are no "advantages" over "regular functions", they are completely different things and trying to compare them doesn't make sense. It's like asking "which is better, variables or if statements?"
Function pointers provide a functionality that would otherwise be unavailable.
In fact passing a pointer of a function is a little bit slower than calling the function itself. But the difference is so little that it can hardly ever have any effect.
As Jon said, it brings more flexibility in some cases, when you can pass the function from one part of your programm to another.
function pointers are used in many situations where you are not sure which function to call exactly. Lets take an example. you want to sort an array. For that you want to write a generic sort function . Now this sorting function needs to compare the array elements. But since array can have any elements (int, floats, strings, user defined types etc), how this sort function can compare the elements. So, in this case, you can pass the ordering-determining function as an argument to this sort function and based on that it can sort the array. Also, it is usefull in another way as well. Lets say you want to sort an array of string (a string of numbers). you may want to sort it numerrically or in alphabatically.
In this case, when you want to sort nnumerically, you can pass compare function which compares based on the value of string converted to int. and so on...
I have a bunch of structs in C++. I'd like to save it to file and load them up again. Problem is a few of my structs are pointers to base classes(/structs). So i'd need a way to figure out the type and create it. They really are just POD, they all have public members and no constructors.
What is the easiest way to save and load them from file? I have a LOT of structs and the only types i use are ints, pointers or c strings. I am thinking i could do some macro hacks. But really i have no idea what i should do.
Have you tried the Boost serialization library?
Don't roll your own here - use something well-developed and tested. One idea is Protocol Buffers
The pointers pose a specific issue: I suppose that multiple struct may actually refer to the same pointer and that you'd like a single pointer to be recreated when deserializing...
The first idea, to avoid boiler-plate code, is to create a compile-time reflexion tool:
BOOST_FUSION_ADAPT_STRUCT
BOOST_FUSION_ADAPT_STRUCT_NAMED
Those 2 macros will generate some wicked information on your struct so that you can then use them with Fusion algorithms, which cross the gap between compile-time and run-time.
Now, you need something that will be able to serialize and deserialize your data. Deserialization is usually a bit more difficult, though here you have the advantage of no polymorphism (which always makes things difficult).
Normally, on a first pass you identify the graph of objects to serialize, assign them all an ID, and use this ID in lieu of the pointer when serializing. For deserializing, you use a 3-columns map:
the map is ID -> (pointer to allocated object, list of pointers that could not be set)
allocate all objects, filling the ID map with a pointer to the allocated object each time
when you need to deserialize an ID, look it up in the map, if absent put a pointer to your pointer in the corresponding list
when you put the pointer to the allocated object in the map, take the time to fill all 'not set' pointers (and remove the list at the same time)
Of course, it's better to have frameworks handling it for you. You may try out s11n, if I remember correctly it handles cycles of references.
Sorry in advance for the lengthy explanation!
I have a C++ application that uses a hash_map to store a tree of information that was parsed from a text file. The values in the map are either a child hash_map or a string. These values were parsed from a text file and then stored into the map.
I wanted to avoid having to send the strings and maps as a copy to the hash map assignment function, so when file was parsed, I created a pointer to new string() or a new hash_map() and stored the value into the map as "arbitrary" data (pointer to a void).
However, this poses a pretty big problem when it comes to clean-up, as deleting a void doesn't behave like one would want it to (and it makes sense). I looked for an easy solution by just creating an Object class and made child classes called StringObj and HashMap, which stored their respective data, and the appropriate destructor was called since the hash_map value type was changed to a pointer to an Object.
Is there an easier way to solve this? I looked into dynamic casting and thought it might work well, since I could catch the exception from the failed cast, and treat it appropriately, but I can't help but feel there might be a simpler solution, or that I'm over-complicating it a bit.
Suggestions?
Thanks in advance,
Jengerer
Use boost::variant (which is equivalent to a C++ union for user-defined types), C++ union (applicable in this case as you're working with only pointers) or boost::any (which can store any type) to store a pointer to either hash_map or string.
One other option is that you could store a std::pair<hash_map*, string*> for each entry in the hash map. Obviously set the unused pointer in each pair to NULL so you can tell which is used and which isn't.
Debatable whether that's neater than your approach or not, although I would hazard that it's less code since you don't need definitions of Object, StringObj and HashMap.