I am working on a project and dealing with shared_ptr's. The program is working and giving the correct output. However upon looking at the logs i notice that at some points in the program the reference count is having a particular value. The sample reproducible program is shown below:
int age = 12;
NAME(std::string m_name, int m_age):name(m_name), age(m_age)
std::cout<<"NAME Parametrised "<<std::endl;
NAME(const NAME& rhs):name(rhs.name), age(rhs.age)
std::cout<<"NAME Copy constructor"<<std::endl;
SURNAME(const std::vector<std::vector<std::shared_ptr<NAME>>> &m_vec):vec_2d(m_vec)
std::cout<<"Refernce count in SURNAME para constructor: "<<vec_2d.at(0).at(0).use_count()<<std::endl;
OUTPUT of the above program
Reference count in SURNAME para constructor: 3
As we can see in the output the reference count is 3 inside the constructor. I think that when we write temp_2dvec.push_back(temp_vector); the reference count is increased by 1 and then when we write obj.vec_SURNAME.push_back(temp_2dvec); the reference count again increases by 1 and finally becomes 3. Now my questions are:
1. Is there a way to avoid this increase in reference count and instead move the share_ptr's ? If yes then how? For example, i tried using temp_2dvec.push_back(std::move(temp_vector)); and then there is no increase in reference count in this step. Is doing this okay here in this step or is it some kind of UB?
2. When i try to do the same and use the statement obj.vec_SURNAME.push_back(std::move(temp_2dvec)); then the reference count still increases even when i used std::move() here. How is this happening?
Note that the variables temp_vector and temp_2dvec are just temporary variables that i made to hold the vectors. They are used only once for pushing purposes. So i will not use them. So it is safe to move from them. How can i safely achieve this, that is no increase in reference count should be there when pushing onto the vectors ?
3. Also, are my 2 comments correct(those which i wrote just to the right of statements in the main program)? That is, the reference count are increased at those 2 steps or are they increased at some other area/step of the program which i am missing.
Since keeping reference count is expensive that is why i am bothered about it. Also, this is an example to show what i want to achieve. The actual project has multiple loops which each runs for 100s or more times. So here i have given the example for just one or 3 pointers but i have 1000s of pointers and keeping their reference count is expensive(in terms of performance).
The actual project has multiple loops which each runs for 100s or more times.
Do you have actual evidence that keeping the refcount is a performance problem? It takes less time to increment it than it takes for light to travel from the display you're reading right now to your eye. If you have 10,000 pointers and adjust them 100 times, then it might take 0.1ms to adjust them all.
So you have a 0.1ms performance problem? Probably not. If you have a performance problem then measure your code, find the actual hot spots and fix them. Right now you're probably doing premature optimization.
1. Moving temp_vector into an element in temp_2d_vector will indeed not increase the reference counts, since no new instances of std::shared_ptr<NAME> are being created.
2. Because the AN constructor takes a const reference to the vector, so the constructor has no means to std::move() from an rvalue reference, if it was actually passed one.
3. Yes, the reference count is increased when the vectors are copied.