c++ - 移动构造函数永远不会被调用

标签 c++ c++11 compiler-optimization move-constructor

我写了下面的代码:

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

相关文章:

c++ - 传递右值加注不能绑定(bind)到左值

java - 用另一个最终静态变量初始化最终静态变量的内存消耗

c++ - 在 C/C++ 中 x[i] * y[i++] 总是等于 x[i] * y[i]

c++ - vc++ 中未处理的异常 - HRESULT 失败

c++ - QtCreator LNK2019 外部库错误

c++ - 如何返回一个 lambda 函数?

C++ 11 : is a defaulted copy constructor user declared?

c++ - 使用 -fno-inline 对 memcmp 进行错误的 GCC 9(及更高版本)优化

c++ - CMake:尝试将链接库添加到未在此目录中构建的目标

c++ - stdafx.cpp 中变量的定义