First of all, note that in C ++, unlike Java, users can define value types. This means that there are 2 ^ 32 * 2 ^ 32 * 2 ^ 8 possible values โโfor routing_entry. If you want, you can think of routing_entry as a 72-bit primitive type, although you should be a little careful with the analogy.
Thus, in Java route can be NULL, and there are 2 ^ 32 * 2 ^ 32 * 2 ^ 8 + 1 different values โโare useful for the variable a routing_entry . In C ++, it cannot be null. In Java, โemptyโ can mean returning a null reference. In C ++, only pointers can be empty, and routing_entry not a pointer type. Therefore, in your code, in this case, โemptyโ means โI donโt know how important this thing is because I never initialized it or assigned it to itโ.
In Java, the routing_entry object will be allocated on the heap. In C ++, you do not want to do this if you do not need it, because memory management in C ++ requires effort.
You have a few (good) options:
1) add a field to the routing record to indicate that it has been initialized. Most likely, this will not make the structure larger due to the requirements of complementing and aligning your implementation:
struct routing_entry { unsigned long destSeq;
Why not use bool? Because the standard helps sizeof(bool) != 1 . It is possible that bool is implemented as an int, especially if you have an old C ++ compiler. This will make your structure larger.
Then make sure that the structure is included at 0 in your function, and not in the garbage on the stack:
routing_entry Cnode_router_aodv::consultTable(unsigned int destinationID ) { routing_entry route = {}; if ( routing_table.find(destinationID) != routing_table.end() ) route = routing_table[destinationID]; return route; // will be "empty" if not found }
And make sure that all participants on the map have an initialized field other than zero. Then the caller checks the initialization.
2) Use the "magic" values โโof existing fields as markers.
Suppose, for the sake of argument, that you never do routes with hopCount 0. Then, as long as you do the 0-initialization, as mentioned above, callers can check hopCount! = 0. The maximum type values โโare also good flag values โโ- since you limit your routes to 256 jumps, most likely you will not do any harm by limiting them to 255 jumps. Instead of callers having to remember this, add a method to the struct:
struct routing_entry { unsigned long destSeq;
Then you will initialize as follows:
routing_entry route = {0, 0, -1};
or if you are worried about what will happen when you change the order or number of fields in the future:
routing_entry route = {0}; route.hopCount = -1;
And the caller:
routing_entry myroute = consultTable(destID); if (myroute.routeFound()) { // get on with it } else { // destination unreachable. Look somewhere else. }
3) The subscriber goes to routing_entry by pointer or non-const reference. Callee fills the response to this and returns a value indicating whether it succeeded or not. This is usually called "out param" because it kind of mimics a function that returns routing_entry and bool.
bool consultTable(unsigned int destinationID, routing_entry &route) { if ( routing_table.find(destinationID) != routing_table.end() ) { route = routing_table[destinationID]; return true; } return false; }
Caller Call:
routing_entry route; if (consultTable(destID, route)) { // route found } else { // destination unreachable }
By the way, when using a card, your code when it searches for an identifier twice. You can avoid this as follows, although this is unlikely to significantly affect the performance of your application:
map< unsigned long int, routing_entry >::iterator it = routing_table.find(destinationID); if (it != routing_table.end()) route = *it;