代码之家  ›  专栏  ›  技术社区  ›  Cheok Yan Cheng

在赋值运算符函数中,数组是否隐式地为memcpy

c++
  •  5
  • Cheok Yan Cheng  · 技术社区  · 14 年前

    好啊。我们知道以下代码无法编译。

    char source[1024];
    char dest[1024];
    // Fail. Use memcpy(dest, source, sizeof(source)); instead.
    dest = source;
    

    但是,可以编译以下代码并正确地执行操作。

    class A {
        char data[1024];
    };
    A source;
    B dest;
    dest = source;
    

    我想知道,在运算符赋值函数中,数组是否隐式地是memcpy?

    以下是完整的测试代码。


    #include <cstdio>
    #include <memory>
    
    class A {
    public:
        char data[1024];
    };
    
    int main() {
        {
            A source;
            A dest;
    
            // Initialization
            char *data = "hello world";
            memcpy (source.data, data, strlen(data) + 1);
    
            printf ("source.data = %s\n", source.data);
            printf ("address source.data = %x\n", source.data);
    
            // Works! Does this in the operator assignment function, memcpy is
            // being performed implicitly on array.
            dest = source;
    
            printf ("dest.data = %s\n", dest.data);
            printf ("address dest.data = %x\n", dest.data);
        }
    
        {
            char source[1024];
            char dest[1024];
    
            // Initialization
            char *data = "hello world";
            memcpy (source, data, strlen(data) + 1);
    
            printf ("source = %s\n", source);
            printf ("address source = %x\n", source);
    
            // '=' : left operand must be l-value
            // dest = source;
            // Works with memcpy.
            memcpy(dest, source, sizeof(source));
    
            printf ("dest = %s\n", dest);
            printf ("address dest = %x\n", dest);
        }
    
        getchar();
    }
    
    //RESULT :
    //source.data = hello world
    //address source.data = 12fb60
    //dest.data = hello world
    //address dest.data = 12f758
    //source = hello world
    //address source = 12f344
    //dest = hello world
    //address dest = 12ef3c
    
    3 回复  |  直到 14 年前
        1
  •  2
  •   YeenFei    14 年前

    如果没有找到子元素的copy ctor/assignment op,则编译器生成的copy ctor/assignment op是按位拷贝。

    编辑 :
    这里是显示概念的修改测试用例。

    #include <cstdio>
    #include <memory>
    
    class someElement
    {
    public:
        someElement() : theData(0) {}
        // Intentionally copy-edit
        someElement(const someElement& src) : theData(src.theData + 1) {}
        ~someElement(){}
    
        someElement& operator=(const someElement& rhs)
        {
            theData = rhs.theData - 1;
            return *this;
        }
    
        char    theData;
    };
    
    class A {
    public:
        someElement data[1024];
    };
    
    int main() {
        {
            A source;
            A dest;
    
            // Initialization
            char *data = "hello world";
            memcpy (source.data, data, strlen(data) + 1);
    
            printf ("source.data = %s\n", source.data);
            printf ("address source.data = %x\n", source.data);
    
            // Works! Does this in the operator assignment function, memcpy is
            // being performed implicitly on array.
            dest = source;
    
            printf ("dest.data = %s\n", dest.data);
            printf ("address dest.data = %x\n", dest.data);
        }
    
        {
            someElement source[1024];
            someElement dest[1024];
    
            // Initialization
            char *data = "hello world";
            memcpy (source, data, strlen(data) + 1);
    
            printf ("source = %s\n", source);
            printf ("address source = %x\n", source);
    
            // '=' : left operand must be l-value
            // dest = source;
            // Works with memcpy.
            memcpy(dest, source, sizeof(source));
    
            printf ("dest = %s\n", dest);
            printf ("address dest = %x\n", dest);
        }
    
        getchar();
    }
    
        2
  •  9
  •   Chubsdad    14 年前

    这句引用标准的话有帮助吗?它很安静,不言自明

    抱歉,删除了我以前的答案,它与复制构造函数相关,而不是复制分配运算符。

    $128/30-

    隐式定义的副本分配 非联合类X的运算符 执行的MemberWise副本分配 它的子对象。直接基地 在 他们声明的顺序 基本说明符列表,然后 x的立即非静态数据成员 按以下顺序分配 他们是在班上宣布的 定义。分配每个子对象 以适合其类型的方式:

    如果子对象是类类型, 的复制分配运算符 类被使用(就像通过显式 资格;也就是说,忽略任何 可能的虚拟覆盖函数 在派生类中);

    如果 子对象是一个数组,每个元素 以适当的方式分配给 元素类型;

    如果子对象 是标量类型,内置 使用赋值运算符。

        3
  •  4
  •   Steve Townsend    14 年前

    operator= 如果没有显式实现,则执行类内容的memberwise副本。对于封装的数组,这是可行的,但通常需要注意确保对类的数据进行适当的深度复制。