在赋值运算符函数中,数组是memcpy隐式的

时间:2010-10-22 02:41:11

标签: c++

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

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 个答案:

答案 0 :(得分:9)

这引用标准帮助吗?这是安静的自我解释

抱歉,删除了我之前的答案,该答案与复制构造函数有关,而不是复制赋值运算符。

$ 12.8 / 30-

  

隐式定义的副本分配   非联合类X的运算符   执行成员复制分配   它的子对象。直接基地   首先分配X的类   他们在宣言中的顺序   base-specifier-list,然后是   X的直接非静态数据成员   按顺序分配   他们在课堂上宣布   定义。每个子对象都已分配   以适合其类型的方式:

     

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

     

- 如果   subobject是一个数组,每个元素都是   以适当的方式分配   元素类型;

     

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

答案 1 :(得分:4)

operator=,如果没有明确实现,则执行类内容的成员副本。对于封装数组,这将起作用,但通常需要注意确保正确深度复制类的数据。

答案 2 :(得分:2)

如果没有为子元素找到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();
}