Search code examples
c++shared-ptrsmart-pointersrvo

How does shared_ptr increase counter when passed by value?


I have this sample code below. I know little bit about RVO (return value optimization) and how copy constructor and assignment operator are skipped during the optimization and return of the value is placed directly on the memory on the left. So if shared pointer does the RVO how does the shared pointer know when to increase its counter? Because for some reason I thought shared pointer class would know when to increase counter based on the number copies or assignment it made.

#include <iostream>
#include <memory>
using namespace std;
class A{
public:
    A(){}
    A(const A& other){ std::cout << " Copy Constructor " << std::endl; }
    A& operator=(const A&other){
        std::cout << "Assingment operator " <<  std::endl;        
        return *this;
    }    
    ~A(){
        std::cout << "~A" <<  std::endl;
    } 
};

std::shared_ptr<A> give_me_A(){
    std::shared_ptr<A> sp(new A);
    return sp;
}

void pass_shared_ptr_by_val(std::shared_ptr<A> sp){

    std::cout << __func__ << ": count  sp = " << sp.use_count() << std::endl;
    std::shared_ptr<A> sp1 = sp;
    std::cout << __func__ << ": count  sp = " << sp.use_count() << std::endl;
    std::cout << __func__ << ": count sp1 = " << sp1.use_count() << std::endl;
}

void pass_shared_ptr_by_ref(std::shared_ptr<A>& sp){
    std::cout << __func__ << ": count  sp = " << sp.use_count() << std::endl;  
    std::shared_ptr<A> sp1 = sp;
    std::cout << __func__ << ": count  sp = " << sp.use_count() << std::endl;
    std::cout << __func__ << ": count sp1 = " << sp1.use_count() << std::endl;
}

int main(){

    {
        shared_ptr<A> sp3 = give_me_A();

        std::cout << "sp3 count = " << sp3.use_count() << std::endl;
        pass_shared_ptr_by_val(sp3);
        pass_shared_ptr_by_ref(sp3);
    }
return 0;
}

output:

sp3 count = 1


pass_shared_ptr_by_val: count sp = 2

pass_shared_ptr_by_val: count sp = 3

pass_shared_ptr_by_val: count sp1 = 3


pass_shared_ptr_by_ref: count sp = 1

pass_shared_ptr_by_ref: count sp = 2

pass_shared_ptr_by_ref: count sp1 = 2

~A


Solution

  • If there is no copy, nothing needs to be counted.

    If RVO is in play no copy is made, so why would the ref-count need to be increased? There is no extra object to destroy and decrement the ref-count.