Search code examples
c++stringconstructorcopymove

Copy constructor is being called first instead of only move constructor on passing even R-value reference


Hello! I am making my own string class named strings

On passing a R-value move constructor and move assignment operator are being called This is the main function, all i am doing is passing R-value ref, but while debugging only copy are or both move and copy.

    int main()
   {
    strings s1="hey!";
       cout<<"\n";
    s1=strings("bye");
       cout<<"\n";
    s1="Hello";
       cout<<"\n";
   strings s2= strings{"Rhythm"};
    s2.print();
    return 0;
   }

   

 //move comstructor
strings::strings(strings &&obj):s{obj.s}
{
  std::cout<<"Calling move const\n";
  obj.s=nullptr;
}
   

 //move assinment operator
   strings& strings::operator=(strings &&obj)
{
    std::cout<<"Using move\n";
    if(this==&obj){
        return *this;
    }
    delete[] s;
    s=obj.s; 
    obj.s=nullptr;
    return *this;
}
       
     //copy constructor;
strings::strings(const strings &obj)
{
   s=new char[strlen(obj.s)+1];
   strcpy(this->s,obj.s);
} 
 

The output window


Solution

  • An moving assignment (not an assignment initialization) requires a move operator=(strings&&). It is not available if you defined own copy constructor. Note, that in situation like this

    struct S {
        S() {}
        S(const S &obj) {  std::cout << "Copy ctor" << std::endl;}
        S(S &&obj) {  std::cout << "Move ctor" << std::endl;}
        S& operator=(const S &obj) {  std::cout << "Copy =" << std::endl; return *this;}
        S& operator=(S &&obj) {  std::cout << "Move =" << std::endl; return *this;}
    };
    
    int main()
    {
        S a = S();
        a = S();
    }
    

    with C++11 compiler the declaration line wouldn't even produce output, because no copy or move did happen, it was elided.