最近一直在研究 C++11 中的移动语义。我印象深刻,迫不及待地想弄脏手并尝试一下。以下是我的代码:
#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();
}
(我从1引用了一些代码)
代码可能看起来很长,但实际上非常幼稚,只是一个转储数组。
在第 67 行,我特意用右值创建了 b,并希望看到移动构造函数是如何被调用的。但令人失望的是,这个程序的输出是:
Constructor: 0x7fff51d60be0
Temp ArrayWrapper created!
This address: 0x7fff51d60be0
Destructor: 0x7fff51d60be0
打印出来的三个地址是一样的,根本没有调用move构造函数!事实上,我后来尝试删除移动构造函数,程序仍然编译并给出了相同的输出!而且如果你仔细看,你会发现构造函数只被调用一次,在构造a的时候。也就是说,在构造 b 时,根本不会调用构造函数,既不移动也不复制!
我真的很困惑。谁能告诉我为什么没有触发移动构造函数,以及究竟 b 是如何构造的?