我是移动构造函数的新手,我从一些网站调查并尝试使用Visual Studio 11 Express Beta ..
以下是我的测试代码......
#include <iostream>
using namespace std;
class Foo
{
public:
Foo()
: Memory(nullptr)
{
cout<<"Foo Constructor"<<endl;
}
~Foo()
{
cout<<"~Foo Destructor"<<endl;
if(Memory != nullptr)
delete []Memory;
}
Foo(Foo& rhs)
: Memory(nullptr)
{
cout<<"Copy Constructor"<<endl;
//allocate
//this->Memory = new ....
//copy
//memcpy(this->Memory, rhs.Memory...);
}
Foo& operator=(Foo& rhs)
{
cout<<"="<<endl;
}
void* Memory;
Foo(int nBytes) { Memory = new char[nBytes]; }
Foo(Foo&& rhs)
{
cout<<"Foo Move Constructor"<<endl;
Memory = rhs.Memory;
rhs.Memory = nullptr;
}
};
Foo Get()
{
Foo f;
return f;
//return Foo();
}
void Set(Foo rhs)
{
Foo obj(rhs);
}
int main()
{
Set(Get());
return 0;
}
我不知道为什么它不会进入移动构造函数。
它实际上是来自Get();
的Rvalue如果我从const构造函数修改了非常量复制构造函数,
它将进入移动构造函数。行为改变了......
有人可以解释为什么会这样吗?
答案 0 :(得分:1)
#include <iostream>
using namespace std;
class Foo
{
public:
Foo():
Memory(nullptr)
{
cout<< this << "Foo Constructor"<<endl;
}
~Foo()
{
cout<< this << "~Foo Destructor"<<endl;
if(Memory != nullptr)
delete []Memory;
}
Foo(Foo& rhs)
:Memory(nullptr)
{
cout<<this << "Copy Constructor"<<endl;
//allocate
//this->Memory = new ....
//copy
//memcpy(this->Memory, rhs.Memory...);
}
Foo& operator=(Foo& rhs)
{
cout<<"="<<endl;
}
void* Memory;
Foo(int nBytes) { Memory = new char[nBytes]; }
Foo(Foo&& rhs)
{
cout<<this << "Foo Move Constructor"<<endl;
Memory = rhs.Memory;
rhs.Memory = nullptr;
}
};
Foo Get()
{
Foo f;
cout << &f << "f" <<endl;
return f;
}
void Set(Foo rhs)
{
Foo obj(rhs);
cout << &obj << "obj"<<endl;
}
int main()
{
Set(Get());
return 0;
}
...输出
0x7fffe38fa0a0 Foo Constructor
0x7fffe38fa0a0 f
0x7fffe38fa070 Copy Constructor
0x7fffe38fa070 obj
0x7fffe38fa070 ~Foo Destructor
0x7fffe38fa0a0 ~Foo Destructor
答案:由于命名返回值优化,参数rhs在本地构建为局部变量f的别名。 (也就是说rhs和f是相同的实例)。
由于rhs是左值,复制构造函数用于从rhs复制构造obj。