Reputation: 707
I have two classes class A and class B. Class A has a map of type map<int,int>
.
In class A, i have the following definition,
typedef std::map<int, int> mymap;
mymap MYMAP;
A A_OBJ;
// did some insert operations on A_OBJ's MYMAP
I also have the following function in class A that when invoked by B will return A's MYMAP as a copy to class B.
A::mymap A::get_port(){
// Returns A's map
return this -> MYMAP;
}
In class B,
void B::initialize_table(){
A::mymap port_table = A_OBJ.get_port();
cout<< "size of ports table at A is"<<port_table.size());
}
Code got compiled with out any issue. The only problem is that even if I insert some data to A's map, B always shows that A's map has 0 elements.
I have a timer at B which calls initialize_table()
every 2s and it is supposed to get the latest copy of the map from A. Not sure where it went wrong.
Any help is appreciated. Thanks.
Upvotes: 1
Views: 97
Reputation: 16935
You're correct that you're creating a copy of the std::map
. The way to fix this is by initializing a reference to the map.
Consider the following stub:
#include <iostream>
#include <map>
using my_map = std::map<int, int>;
struct A {
A() : m() {}
my_map& get_my_map() { return m; }
my_map m;
};
struct B {
B() : a() {}
void initialize_map_ref();
void initialize_map_val();
void print_index_42() { std::cout << a.get_my_map()[42] << '\n'; }
A a;
};
void B::initialize_map_ref() {
// notice this is a reference
my_map& m = a.get_my_map();
m[42] = 43;
}
void B::initialize_map_val() {
// notice this is a copy
my_map m = a.get_my_map();
m[42] = 43;
}
int main() {
B b;
b.initialize_map_ref();
b.print_index_42();
return 0;
}
B::initialize_map_ref
initializes a reference (i.e., a reference to the map within a
), where B::initialize_map_val
creates a copy and initializes the copy. The copy dies after the call, so outside of the call, m[42] == 0
. The reference initialization, on the other hand, persists because you've changed a reference to the underlying object.
Ideone: With reference and with value.
Upvotes: 1
Reputation: 816
I suggest returning by an R-value reference for the sake of efficiency (i.e. A::mymap&& A::get_port(){return A::mymap(this -> MYMAP;) };
).
I can only see your code failing in one of two circumstances:
you are updating A_OBJ.MYMAP
after you call A_OBJ.get_port()
This will cause the copy to be out of date.
or you are updating A_OBJ.get_port()
. and then calling A_OBJ.get_port()
again. This will cause the copy to be modified but the original map, to be left unmodified, resulting in the second call to A_OBJ.get_port()
to not consider any changes made to the value returned by the previous.
Depending on what you want you may want to return a (const) reference to the map.
EDIT I mistakenly originally thought that A::mymap port_table = A_OBJ.get_port();
would cause two copies, but now I realize it will cause a copy and then a move, it would also do that in the rvalue case, however that is likely to introduce undefined behaviour (I think) because of returning a reference to a temporary... (originally I had it return this -> MYMAP
but would be an error as it would try to bind an lvalue (this -> MYMAP
) to an rvalue reference)
Upvotes: 0