额外移动构造函数调用的说明

问题描述 投票:0回答:1

我将直接转到代码并解释我在这里想要理解的内容。

class MyInt 
{
    unique_ptr<int> ptr;
    public:
        MyInt(int val)
        { 
            cout << __PRETTY_FUNCTION__ << "this: <" << this << ">, val: <" << val << ">" << endl;
            ptr = make_unique<int>(val);
        }
        ~MyInt()
        {
            cout << __PRETTY_FUNCTION__ << "this: <" << this << ">" << endl;
        }
       
        MyInt(MyInt&& other) noexcept: ptr(move(other.ptr))
        { 
            cout << __PRETTY_FUNCTION__ << "this: <" << this << ">, other :<" << &other << ">" << endl;
        }

        MyInt& operator=(MyInt&& other) noexcept
        { 
            cout << __PRETTY_FUNCTION__ << "this: <" << this << ">, other :<" << &other << ">" << endl;
            if (this != &other)
            {
                ptr = move(other.ptr);
                other.ptr = nullptr;
            }

            return *this;
        }
};

int main(int argc, char *argv[])
{
    MyInt *aptr = new MyInt[2]{11, 22};

    for (size_t i = 0; i < 2; ++i)
    {
        cout << "aptr[" << i << "] :" << &aptr[i] << endl;
    }

    cout << "deleting :" << endl;
    
    delete [] aptr;

    cout << "exiting" << endl;

    return 0;

}

这段代码的输出是:

onkar@DESKTOP-MTXXX:~/CppDesignPatterns/build$ ./DesignPatterns/Test
MyInt::MyInt(int)this: <0x7ffe7a274e30>, val: <11>
MyInt::MyInt(MyInt&&)this: <0x7ffe7a274e50>, other :<0x7ffe7a274e30>
MyInt::MyInt(MyInt&&)this: <0x603000000048>, other :<0x7ffe7a274e50>
MyInt::~MyInt()this: <0x7ffe7a274e50>
MyInt::~MyInt()this: <0x7ffe7a274e30>
MyInt::MyInt(int)this: <0x7ffe7a274e70>, val: <22>
MyInt::MyInt(MyInt&&)this: <0x7ffe7a274e90>, other :<0x7ffe7a274e70>
MyInt::MyInt(MyInt&&)this: <0x603000000050>, other :<0x7ffe7a274e90>
MyInt::~MyInt()this: <0x7ffe7a274e90>
MyInt::~MyInt()this: <0x7ffe7a274e70>
aptr[0] :0x603000000048
aptr[1] :0x603000000050
deleting :
MyInt::~MyInt()this: <0x603000000050>
MyInt::~MyInt()this: <0x603000000048>
exiting
onkar@DESKTOP-MTXXX:~/CppDesignPatterns/build$

从上面的代码和输出中,任何人都可以很容易地理解创建临时对象、分配内存并将临时对象移动到数组 aptr 的内存中的适当位置。

我在这里无法理解的是额外的调用 -

MyInt::MyInt(MyInt&&)this: <0x7ffe7a274e50>, other :<0x7ffe7a274e30>

MyInt::MyInt(MyInt&&)this: <0x7ffe7a274e90>, other :<0x7ffe7a274e70>

为什么会发生这些电话?目的是什么(或者可能的目的)?

顺便说一句,我传递给 CMake 来构建此代码的标志是

# Set C++ standards 
set(CMAKE_CXX_STANDARD 14)
set(CMAKE_CXX_STANDARD_REQUIRED ON)

# Disable copy elision, RVO -fno-elide-constructors
#set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS_DEBUG} -g -Wall")
set(CMAKE_CXX_FLAGS_DEBUG "${CMAKE_CXX_FLAGS_DEBUG} -fsanitize=address -fno-elide-constructors -g")

即禁用复制省略。

c++ c++17
1个回答
0
投票

-fno-elide-constructors
删除保证省略。也就是说,对象的创建分几个步骤进行:

Create temporal MyInt (11) 
Move MyInt (11) to instance inside of temporal initialization list.
Move MyInt (11) to 1st element of array 
Create temporal MyInt (22)
Move MyInt (22) to instance inside of temporal initialization list.
Move MyInt (22) to 2nd element of array 

标准行为是在创建数组元素的位置构造数组元素,而不是表达式图的走向:

Create 1st element of array MyInt (11)
Create 2nd element of array MyInt (22)
© www.soinside.com 2019 - 2024. All rights reserved.