我写了下面的代码:
#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()
看起来编译器正在做一些优化。如果是这种情况,那么为什么我们需要移动构造函数或移动赋值运算符。
最佳答案
This does not call the move constructor. Is there something is wrong?
不,没有什么问题。
It might look like the compiler is doing some optimisation.
这正是编译器所做的。
If this the case then why we need move constructor or move assignment operator for our case.
您的类需要自定义移动构造函数和赋值运算符,因为隐式生成的构造函数和赋值运算符无法正确处理分配的资源。
仅仅因为编译器可能会优化,并不是将它们排除在外的好理由。特别是因为在其他一些程序中,该移动根本无法优化。
附注。
析构函数中的if (ptr)
是多余的。删除nullptr就可以了。您也不必在 operator=
中进行检查,这很好。
deleteMe
是一个危险的函数。删除 self 在一些非常模糊的情况下可能很有用,但你的类没有表现出任何需要它。在非动态实例上调用此函数的行为将是未定义的。
在移动和复制构造函数中将 ptr
初始化为 null 是多余的,因为您在构造函数主体中无条件地覆盖该值。
关于c++ - 移动构造函数永远不会被调用,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/52577701/