C ++阵列深层复制构造函数

时间:2018-04-06 17:30:21

标签: c++ arrays copy-constructor

来自"编程:使用C ++的原理和实践 - Bjarne Stroustrup"复制数组的例子:

  

18.3.1复制构造函数

class vector {
    int sz; // the size
    double* elem; // a pointer to the elements
public:
    vector(int s) :
            sz { s }, elem { new double[s] } {
        for (int i = 0; i < sz; ++i)
            elem[i] = 0.0; // initialize
    } // constructor
    ~vector() {
        delete[] elem;
    } // destructor
    int size() const {
        return sz;
    } // the current size
    double get(int n) const {
        return elem[n];
    } // access: read
    void set(int n, double v) {
        elem[n] = v;
    } // access: write
    vector(const vector& arg)
// allocate elements, then initialize them by copying
    :
            sz { arg.sz }, elem { new double[arg.sz] } {
        copy(arg.elem, arg.elem + arg.sz, elem); // std::copy(); see §B.5.2
    }
};
int main(int argc, char ** argv) {
    vector v(3); // define a vector of 3 elements
    v.set(2, 2.2); // set v[2] to 2.2
    vector v2 = v;
    v.set(1, 99); // set v[1] to 99
    v2.set(0, 88); // set v2[0] to
    cout << v.get(0) << ' ' << v2.get(1);
    return 0;
}

为什么实际的数组成员被复制而不仅仅是他们的地址? elem是一个指针,在复制命令中不会被取消引用。

2 个答案:

答案 0 :(得分:2)

您的困惑源于值类型引用类型之间的区别。

在标准C ++实践中,除非另有说明,否则所有内容都是值类型。除非另有特别说明,否则对象的副本完全不同。

这就是为什么改变矢量副本不应该改变从复制的原始矢量,而不管矢量函数的内部工作方式如何

在内部使用动态分配的内存实现向量的事实是一个实现细节,它与向量本身的接口没有关系,它本身就是一个值类型(默认情况下)

答案 1 :(得分:1)

回答关于为什么要复制数组成员的问题,而不仅仅是他们的地址。解释浅拷贝和深拷贝之间的区别可能会有所帮助。让我们说我们有两个指向两个不同数组的指针,A和B.

A = [0, 1, 2, 3, 4] 
B = [9, 10, 11, 12, 13] 

让我们将A的内容复制到B.浅拷贝只涉及改变指针。 B = A

这并不总是理想的,因为您在A中更改的任何元素也会在B中更改,因为它们指向内存中的相同位置。

如果执行深层复制,则将所有元素从A复制到B

A = [0, 1, 2, 3, 4] 
B = [0, 1, 2, 3, 4]

如果更改A中的项目,则不会影响B中的项目,即更改

A[0] = 10

然后,

A = [10, 1, 2, 3, 4] 
B = [0, 1, 2, 3, 4]

我希望帮助