代码之家  ›  专栏  ›  技术社区  ›  fredoverflow

C++数组成员在复制控制函数中是如何处理的?

  •  29
  • fredoverflow  · 技术社区  · 14 年前

    这是我很长时间以来一直想知道的事情。举个例子:

    struct matrix
    {
        float data[16];
    };
    

    我知道默认构造函数和析构函数在这个特定的例子中做了什么(什么都不知道),但是复制构造函数和复制赋值操作符呢?

    struct matrix
    {
        float data[16];
    
        // automatically generated copy constructor
        matrix(const matrix& that) : // What happens here?
        {
            // (or here?)
        }
    
        // automatically generated copy assignment operator
        matrix& operator=(const matrix& that)
        {
            // What happens here?
    
            return *this;
        }
    };
    

    是否涉及 std::copy std::uninitialized_copy memcpy memmove 或者什么?

    2 回复  |  直到 9 年前
        1
  •  42
  •   fredoverflow    14 年前

    这就是标准在12.8(复制类对象)中所说的。复制构造:

    每个子对象都以适合其类型的方式复制:

    • 如果子对象是类类型,则使用类的复制构造函数;
    • 如果子对象是数组,则按照与元素类型相应的方式复制每个元素;
    • 如果子对象是标量类型,则使用内置赋值运算符。

    副本分配:

    每个子对象都以适合其类型的方式分配:

    • 如果子对象是类类型,则使用类的复制赋值运算符(如同通过显式限定;即忽略更多派生类中任何可能的虚拟重写函数);
    • 如果子对象是一个数组,则以适合于元素类型的方式分配每个元素;
    • 如果子对象是标量类型,则使用内置赋值运算符。
        2
  •  1
  •   tartaruga_casco_mole    6 年前

    两者都复制数组中的元素(而不是什么都不做或复制指针)。

    struct X
    {
        char data_[100];
    };
    
    
    int main () 
    {
        X orig, copy_assign;
        orig.data_[10] = 'a';
        copy_assign = orig;
        X copy_constructor(orig);
        printf("orginal10:%c, copy_assign10:%c, copy_constructor10:%c\n",orig.data_[10],copy_assign.data_[10],copy_constructor.data_[10]);
        copy_assign.data_[10] = 'b';
        printf("original10:%c, copy_assign10:%c, copy_constructor10:%c\n",orig.data_[10],copy_assign.data_[10],copy_constructor.data_[10]);
        copy_constructor.data_[10] = 'c';
        printf("original10:%c, copy_assign10:%c, copy_constructor10:%c\n",orig.data_[10],copy_assign.data_[10],copy_constructor.data_[10]);
        return 0;
    }
    

    运行结果:

    orginal10:a, copy_assign10:a, copy_constructor10:a
    original10:a, copy_assign10:b, copy_constructor10:a
    original10:a, copy_assign10:b, copy_constructor10:c
    
    • 从结果的第一行,我们可以看到至少复制了一些内容(它要么是数组中的元素,要么是数组指针被复制)。
    • 从接下来的两行中,我们可以看到更改copy assigned objects和copy constructed objects的数组并没有更改原始数组。因此我们得出结论,元素是复制的,而不是数组指针。

    希望这个例子是清楚的。