永远不会调用移动构造函数

Move constructor never gets called

我写了下面这段代码:

#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.

您的 class 需要自定义移动构造函数和赋值运算符,因为隐式生成的构造函数和赋值运算符无法正确处理分配的资源。

仅仅因为编译器可能优化,并不是将它们排除在外的好理由。特别是因为在其他一些程序中,移动根本无法优化。


PS.

析构函数中的

if (ptr) 是多余的。删除nullptr就好了。您也不在 operator= 中进行检查,这很好。

deleteMe 是一个危险的函数。删除 self 在某些非常模糊的情况下可能很有用,但您的 class 没有显示任何需要它。在非动态实例上调用此函数的行为是未定义的。

在移动和复制构造函数中将 ptr 初始化为 null 是多余的,因为您在构造函数的主体中无条件地覆盖了该值。