Trusted answers to developer questions
Trusted Answers to Developer Questions

Related Tags

constructors
c++

What is a move constructor in C++?

Educative Answers Team

A move constructor allows the resources owned by an rvalue object to be moved into an lvalue without creating its copy.

An rvalue is an expression that does not have any memory address, and an lvalue is an expression with a memory address.

What is an Rvalue reference?

Before jumping on to the rvalue reference, let’s see one of the limitations in C++:

int &j = 20;

The above code snippet will give an error because, in C++, a variable cannot be referenced to a temporary object. The correct way to do it is to create an​ rvalue reference using && :

int &&j = 20;

Temporary objects are often created during the execution of a C++ program.

The best usage of an rvalue reference can be seen in the move constructor.

#include <iostream>
#include <vector>
using namespace std;

class A{
  int *ptr;
public:
  A(){
    // Default constructor
    cout << "Calling Default constructor\n";
    ptr = new int ;
  }

  A( const A & obj){
    // Copy Constructor
    // copy of object is created
    this->ptr = new int;
    // Deep copying
    cout << "Calling Copy constructor\n";
  }

  ~A(){
    // Destructor
    cout << "Calling Destructor\n";
    delete ptr;
  }

};

int main() {

  vector <A> vec;
  vec.push_back(A());

  return 0;

}

Now, when the above code is executed, the default constructor is called at the time that the temporary object A is created. The copy constructor is called as the temporary object of A is pushed back in the vector.

In the above code, there is a serious performance overhead as the temporary object A is first created in the default constructor and then in the copy constructor. The move constructor is used to avoid this performance overhead:

#include <iostream>
#include <vector>
using namespace std;

class A{
  int *ptr;
public:
  A(){
    // Default constructor
    cout << "Calling Default constructor\n";
    ptr = new int ;
  }

  A( const A & obj){
    // Copy Constructor
    // copy of object is created
    this->ptr = new int;
    // Deep copying
    cout << "Calling Copy constructor\n";
  }

  A ( A && obj){
    // Move constructor
    // It will simply shift the resources,
    // without creating a copy.
     cout << "Calling Move constructor\n";
    this->ptr = obj.ptr;
    obj.ptr = NULL;
  }

  ~A(){
    // Destructor
    cout << "Calling Destructor\n";
    delete ptr;
  }

};

int main() {

  vector <A> vec;
  vec.push_back(A());

  return 0;

}

When the above code is executed, the move constructor is called instead of the copy constructor. With the move constructor, the copy of the temporary object of A is avoided. For a large number of push_back statements, using the move constructor is an efficient choice.

Note: a move constructor can be explicitly called, with the move() function, ​for already created objects.

RELATED TAGS

constructors
c++
Copyright ©2022 Educative, Inc. All rights reserved
RELATED COURSES

View all Courses

Keep Exploring