为什么复制构造函数和复制分配运算符调用“memcpy”,而移动 ctor 和移动分配运算符调用“memmove”

Why does the copy constructor and copy assignment operator call `memcpy` whereas the movement ctor and movement assignment operator call `memmove`

提问人:John 提问时间:6/5/2020 最后编辑:John 更新时间:6/6/2020 访问量:224

问:

作为主题,下面列出了相关代码。您可以在 https://godbolt.org/z/mAbmwJ 上检查它。

我完全理解 和 之间的区别,但我不明白它背后的原因。代码引用自一个著名的开源项目,我不会加倍强调代码的正确性,开发人员一定有一些理由这样做。 如果能得到一些帮助,我将不胜感激。memcpy(3)memmove(3)

#include<string.h>
#include<iostream>

#define ENTITYID_UNKNOWN 0x00000000
#define ENTITYID_SEDP_BUILTIN_PUBLICATIONS_WRITER  0x000003c2
#define ENTITYID_SEDP_BUILTIN_PUBLICATIONS_READER  0x000003c1

struct EntityId_t
{
    static constexpr unsigned int size = 4;
    char value[size];
    //! Default constructor. Uknown entity.
    EntityId_t(){
        *this = ENTITYID_UNKNOWN;
    }

    EntityId_t(int id)
    {
        int* aux = (int*)(value);
        *aux = id;
         std::cout << "EntityId_t(int id) constructor" << std::endl;
    }

    /*!
     * @brief Copy constructor
     */
    EntityId_t(
            const EntityId_t& id)
    {
        memcpy(value, id.value, size);
        std::cout << "copy constructor" << std::endl;
    }

    EntityId_t& operator =(
            const EntityId_t& id)
    {
        memcpy(value, id.value, size);
        std::cout << "copy operator() constructor" << std::endl;
        return *this;
    }

    /*!
     * @brief Move constructor
     */
    EntityId_t(
            EntityId_t&& id)
    {
        memmove(value, id.value, size);
        std::cout << "move constructor" << std::endl;
    }

    EntityId_t& operator =(
            EntityId_t&& id)
    {
        memmove(value, id.value, size);
        std::cout << "move operator(EntityId_t&&)" << std::endl;
        return *this;
    }
};



int main()
{
    EntityId_t c_SEDPPubWriter = ENTITYID_SEDP_BUILTIN_PUBLICATIONS_WRITER;
    std::cout << "==============================" << std::endl;

    EntityId_t c_SEDSubscribe;
    c_SEDSubscribe = ENTITYID_SEDP_BUILTIN_PUBLICATIONS_READER;
}

输出:

EntityId_t(int id) constructor
==============================
EntityId_t(int id) constructor
move operator(EntityId_t&&)
EntityId_t(int id) constructor
move operator(EntityId_t&&)
C++ C++11 复制构造函数 move-semantics

评论

0赞 Richard Critten 6/5/2020
当你看到这样的一行:(是)时,你就知道前方有奇怪的事情发生。*this = ENTITYID_UNKNOWN;ENTITYID_UNKNOWN0x00000000
0赞 John 6/6/2020
相反,我认为“===”之后的输出是正确的。我完全可以理解。但是我无法理解“===”之前的输出。我会重新编辑代码以避免误解。我认为它应该调用用户定义的构造函数 EntityId_t(int id) 和运动赋值运算符,
0赞 aschepler 6/6/2020
请注意,第一个语句中的 is 不是赋值运算符。它只是引入了变量的初始值设定项。=main
0赞 John 6/6/2020
你能更详细地解释一下吗?我认为调用用户定义的构造函数来生成一个临时对象。由于它是一个 rvalue(临时对象),因此 complier 会调用 .我哪里错了?ENTITYID_SEDP_BUILTIN_PUBLICATIONS_WRITEREntityId_t(int id)movement assigment operation
0赞 Igor Tandetnik 6/6/2020
EntityId_t c_SEDPPubWriter = ENTITYID_SEDP_BUILTIN_PUBLICATIONS_WRITER;调用构造函数。完全不涉及赋值运算符。对于第一个近似值,和 之间没有区别 - 它是初始化的不同语法(同样,这两种方式都没有赋值)。EntityId_t(int id)SomeClass var = init;SomeClass var(init);

答: 暂无答案