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

Posted

技术标签:

【中文标题】复制控制函数中如何处理 C++ 数组成员?【英文标题】:How are C++ array members handled in copy control functions? 【发布时间】:2011-05-09 00:50:31 【问题描述】:

这是我想了很久的事情。举个例子:

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::copystd::uninitialized_copymemcpymemmove或什么?

【问题讨论】:

这不是真正的 C,而是(主要是)C++。 @DervinThunk 我把问题的标题从 C 改成了 C++ 【参考方案1】:

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

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

如果子对象是类类型,则使用该类的复制构造函数; 如果子对象是一个数组,则以适合元素类型的方式复制每个元素; 如果子对象是标量类型,则使用内置赋值运算符。

复制作业:

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

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

【讨论】:

【参考方案2】:

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

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
从结果的第一行,我们可以看到至少复制了一些内容(它要么是数组中的元素,要么是复制了数组指针)。 从接下来的两行中,我们可以看到更改复制分配对象和复制构造对象的数组并没有改变原始数组。因此我们得出结论,复制的是元素而不是数组指针。

希望这个例子很清楚。

【讨论】:

以上是关于复制控制函数中如何处理 C++ 数组成员?的主要内容,如果未能解决你的问题,请参考以下文章

函数式编程中如何处理副作用?

函数式编程中如何处理副作用?

函数式编程中如何处理副作用?

字符串类型数组的指针运算,C++如何处理这个?

Preact 中如何处理“refs”?

Jenkins一次任务构建中如何处理多个git仓库