最近我一直在研究C++ 11中的移动语义。我印象深刻,我迫不及待地想弄脏手并尝试它们。下面是我的代码: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
要打印是相同的,移动的构造完全不叫这三个地址! 事实上,我后来试图删除移动构造函数,并且程序仍然编译并给出相同的输出!如果你仔细观察一下,你会发现在构造一个构造函数时只会调用一次构造函数。也就是说,当构造b时,根本不会调用构造函数,也不会移动也不会复制!
我真的很困惑。任何人都可以告诉我为什么移动构造函数没有被触发,以及地球上的结构是如何构建的?
复制elision ... –
@KerrekSB第一次听到它,并使用它搜索。印象深刻,谢谢!但是你知道如何强制移动构造函数被调用吗? – seemuch
'-fno-elide-constructors' –