vendredi 11 juin 2021

Using std::move on std::shared_ptr

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:

SAMPLE Program

#include <iostream>
#include<vector>
#include<string>
#include<utility>
#include<memory>
class NAME 
{   
    public:
    std::string name;
    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;
    }
};
class SURNAME 
{
    public:
    std::vector<std::vector<std::shared_ptr<NAME>>> vec_2d;
    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;
    }
    
};
class AN
{
    public:
      std::vector<SURNAME> vec_SURNAME;
};

int main()
{

   
   std::vector<std::shared_ptr<NAME>> temp_vector;
   temp_vector.reserve(3);
   temp_vector.push_back(std::make_shared<NAME>("MIDDLE",43));
   temp_vector.push_back(std::make_shared<NAME>("LAST",54));
   temp_vector.push_back(std::make_shared<NAME>("ANOTHERLAST",54));
   std::vector<std::vector<std::shared_ptr<NAME>>> temp_2dvec;
   temp_2dvec.reserve(1);
   temp_2dvec.push_back(temp_vector);//reference count becomes 2
   
   AN obj;
   
   obj.vec_SURNAME.push_back(temp_2dvec);//reference count becomes 3

   return 0;
}

OUTPUT of the above program

NAME Parametrised 
NAME Parametrised 
NAME Parametrised 
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?
  3. 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 ?
  4. 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.

Aucun commentaire:

Enregistrer un commentaire