【发布时间】:2018-09-30 12:04:32
【问题描述】:
我写了以下代码:
#define LOG cout << __PRETTY_FUNCTION__ << endl;
class MyClass
{
private:
int* ptr;
public:
MyClass()
: ptr(new int(10))
{
LOG
}
~MyClass()
{
LOG
if (ptr)
{
delete ptr;
ptr = nullptr;
}
}
MyClass(const MyClass& a)
: ptr(nullptr)
{
LOG
ptr = new int;
*ptr = *(a.ptr);
}
MyClass& operator=(const MyClass& a)
{
LOG
if (this == &a)
{
return *this;
}
delete ptr;
ptr = new int;
*ptr = *(a.ptr);
return *this;
}
MyClass(MyClass&& a)
: ptr(nullptr)
{
LOG
ptr = a.ptr;
a.ptr = nullptr;
}
MyClass& operator=(MyClass&& a)
{
LOG
if (this == &a)
{
return *this;
}
delete ptr;
ptr = a.ptr;
a.ptr = nullptr;
return *this;
}
void printClass()
{
LOG;
}
};
MyClass function()
{
MyClass m;
return m;
}
int main()
{
MyClass m = function();
return 0;
}
程序的输出:
MyClass::MyClass()
MyClass::~MyClass()
这不会调用移动构造函数。有什么问题吗?
我期待以下输出:
MyClass::MyClass()
MyClass::MyClass(MyClass&&)
MyClass::~MyClass()
MyClass::MyClass(MyClass&&)
MyClass::~MyClass()
MyClass::~MyClass()
看起来编译器正在做一些优化。如果是这种情况,那么为什么我们需要移动构造函数或移动赋值运算符。
【问题讨论】:
-
允许(甚至要求)编译器在某些情况下省略复制和移动,即使构造函数或析构函数有副作用。最好发布您搜索的关键字。对此有很多答案。
-
看起来编译器正在做一些优化。 -- 我希望如此。如果我使用的编译器生成了你说你希望看到的一个小小的 1 行程序的混乱,我会把它扔掉。
-
如果要查看实际调用的移动构造函数,请使用std::move explicitly。
标签: c++ c++11 compiler-optimization move-constructor