Recently I have been studying the move semantics in C++11. I was so impressed that I could not wait to get my hands dirty and try them. The following is my code:
#include <iostream>
using namespace std;
class ArrayWrapper
{
public:
// default constructor produces a moderately sized array
ArrayWrapper ()
: _p_vals( new int[ 64 ] )
, _size( 64 )
{
cout << "Default constructor: " << this << endl;
}
explicit ArrayWrapper (int n)
: _p_vals( new int[ n ] )
, _size( n )
{
cout << "Constructor: " << this << endl;
}
// move constructor
ArrayWrapper (ArrayWrapper&& other)
: _p_vals( other._p_vals )
, _size( other._size )
{
cout << "Move constructor: " << this << endl;
other._p_vals = NULL;
other._size = 0;
}
// copy constructor
ArrayWrapper (const ArrayWrapper& other)
: _p_vals( new int[ other._size ] )
, _size( other._size )
{
cout << "Copy constructor: " << this << endl;
for ( int i = 0; i < _size; ++i )
{
_p_vals[ i ] = other._p_vals[ i ];
}
}
~ArrayWrapper ()
{
cout << "Destructor: " << this << endl;
delete [] _p_vals;
}
void self () {
cout << "This address: " << this << endl;
}
public:
int *_p_vals;
int _size;
};
ArrayWrapper two() {
ArrayWrapper a(7);
cout << "Temp ArrayWrapper created!" << endl;
return a;
}
int main() {
ArrayWrapper b (two());
b.self();
}
(I referenced some code from 1)
The code may look long, but it is actually pretty naive, just a dump array.
On line 67, I deliberately created b with a rvalue and expected to see how the move constructor is called. But disappointingly, the output of this program is:
Constructor: 0x7fff51d60be0
Temp ArrayWrapper created!
This address: 0x7fff51d60be0
Destructor: 0x7fff51d60be0
The three addresses that are printed are the same and the move constructor is not called at all! In fact, I later tried to delete the move constructor, and the program still compiled and gave the same output! And if you look a little carefully, you will find that the constructor is only called once, when constructing a. That is, when b is constructed, no constructor, neither move nor copy, is called at all!
I am really confused. Could anyone please tell me why the move constructor is not triggered, and how on earth b is constructed?