RVO and move semantics

Welcome,

One of my college created this comparsion while handling result values of a function.

The main point of this example is that there was life before C++11 and it wasn't was that bad ;)

Let's see a simple example:

We all know that a true coder only use 0's and 1's, but we not so low level guys have many help from the compiler programmers. This one is RVO. If the compiler is capable and could figure out our passing parameters then its elide a copy.

But with C++11 we can use move semantics, which also tries to reduce resource copy and keeps data handling faster.

Take a look at this code snippet:

// header file
class MoveMe
{
public:
    MoveMe();
    MoveMe(const MoveMe&);
    MoveMe(MoveMe&&);
    ~MoveMe();

public:
    std::string _string;
};

// implementation
MoveMe::MoveMe()
{
    std::cout << "MoveMe constructor called" << std::endl;
    _string = "constructed";
}

MoveMe::MoveMe(const MoveMe&)
{
    std::cout << "MoveMe copy constructor called" << std::endl;
    _string = "copy constructed";
}

MoveMe::MoveMe(MoveMe&&)
{
    std::cout << "MoveMe move constructor called" << std::endl;
    _string = "move constructed";
}

MoveMe::~MoveMe()
{
    std::cout << "MoveMe destructor called on a " << _string << " object" << std::endl;
}

We have a class which is prints out a line at specific events.

The two types of object creation:

MoveMe moveMeMoveMe()
{
    MoveMe result;

    return std::move(result);
}

MoveMe justGiveMeMoveMe()
{
    MoveMe result;

    return result;
}

Now we create and destroy this declaration objects at different situations:

    {
        std::cout << "Create MoveMe on stack" << std::endl;
        MoveMe mm;
    }
    {
        std::cout << "That's a copy" << std::endl;
        MoveMe mm;
        MoveMe copy(mm);
    }
    {
        std::cout << "RVO" << std::endl;

        MoveMe mm(justGiveMeMoveMe());
    }
    {
        std::cout << "MOVE" << std::endl;

        MoveMe mm(moveMeMoveMe());
    }
  1. First we create on the stack and release it at line 4. Nothings strange.
  2. Next we use the copy constructor, and both of the stack aquired objects gets released at line 9.
  3. From line 11 we will pass an object which is a return result of a function.
  4. Last we will move an object which is a return result of another function.

Lets see the output (mingw 5.7)

/> Create MoveMe on stack
/> MoveMe constructor called
/> MoveMe destructor called on a constructed object
/> That is a copy
/> MoveMe constructor called
/> MoveMe copy constructor called
/> MoveMe destructor called on a copy constructed object
/> MoveMe destructor called on a constructed object
/> RVO
/> MoveMe constructor called
/> MoveMe destructor called on a constructed object
/> MOVE
/> MoveMe constructor called
/> MoveMe move constructor called
/> MoveMe destructor called on a constructed object
/> MoveMe destructor called on a move constructed object

 

We can compare that our MOVE still have two objects, as we normally await and what RVO could elide for us.

The code example could be downloaded from HERE!

 

Conclusion:

Aristotle was right: "The more you know, the more you know you don't know."

When I'm eager to apply the latest technologies, then I have to first know the current ones. Replace those, which are get old and have a better replacement.

 

Thanks for reading.

 

 

Date modified: 
Monday, January 2, 2017 - 00:15
Date published: 
Keywords: 
C++11,RVO,Move semantics,Move constructor
Author: