为什么下面的类不对数组 arr 进行浅拷贝?

Why isn't the following class doing shallow copy for the array arr?

本文关键字:arr 浅拷贝 数组 为什么      更新时间:2023-10-16

我正在根据固定大小的数组实现以下类的堆栈:

class Stack{
    private:
        int arr[1000];
        int size;
    public:
        Stack(){ size=0; }
        int top(){
            assert(size>0);
            return arr[0];
        }
        void push(int v){ assert(size<1000); arr[size++] = v; }
        void pop(){ assert(size>0); size--; }
        bool empty(){ return size==0; }
        bool is_equal(Stack s){
            Stack c = *this;
            while(!c.empty() && !s.empty()){
                if (c.top() != s.top())
                    return false;
                c.pop();
                s.pop();
            }
            return c.empty() && s.empty();
        }
};

根据我的知识,IS_Equal方法的第一行将创建另一个对象(C),但ARR属性将指向原始对象的相同数据。因此,来自C的弹出数据将影响原始堆栈的arr。

令人惊讶的是,这没有发生。

堆栈C ARR的地址与原始堆栈ARR的地址不同,并且数据正确复制,好像我已经超载了分配运算符。

我想念什么吗?

据我所知,iS_qual方法的第一行将 创建另一个对象(c),但是ARR属性将指向相同 原始对象的数据。因此,来自C的弹出数据将影响 原始堆栈的arr。

不,那是错误的。Stack对象将被复制并获得自己的存储空间。复制数组意味着将其所有元素复制到内存中的不同部分。c*this是两个不同的Stack对象,具有两个不同的数组。

根据我的知识,IS_Equal方法的第一行将创建另一个对象(C),但ARR属性将指向原始对象的相同数据。

不,不会。没有像制作固定阵列的浅拷贝这样的东西。this中数组的元素将复制到新对象c中的数组。就像您传递给 is_equal()的任何 Stack对象的元素将被复制到 s参数中的数组,因为您是通过value 。

如果您真的想共享数组,则需要使用new[]std::malloc()动态分配数组,然后让Stack存储一个指针到该数组。将指针从一个对象复制到另一个对象将为您提供您正在考虑的浅拷贝语义。

因此,从C中弹出数据将影响原始堆栈的arr。

不,不会,因为c具有独立于sthis中的数组的数组。

堆栈C ARR的地址与原始堆栈的ARR

的地址不同

正确。因为它们是内存中的单独数组。

数据被正确复制,好像我已经超载了分配运算符。

是的,因为您没有实现自己的复制构造函数或复制分配运算符,因此编译器为您隐含地实施了它们。隐式实现将将数组元素从源对象的数组复制到目标对象的数组。

和顺便说一句,您的 is_equal()可以实现,而无需完全制作任何副本:

class Stack {
    private:
        int arr[1000];
        int size;
    public:
        ...
        bool is_equal(const Stack &s) const {
            if (size != s.size)
                return false;
            for (int i = 0; i < size; ++i) {
                if (arr[i] != s.arr[i])
                    return false;
            }
            return true;
        }
        ...
};

或简单:

#include <algorithm>
class Stack {
    private:
        int arr[1000];
        int size;
    public:
        ...
        bool is_equal(const Stack &s) const {
            // pre-C++14...
            return (size == s.size) && std::equal(arr, arr + size, s.arr);
            // C++14 and later...
            return std::equal(arr, arr + size, s.arr, s.arr + s.size);
        }
        ...
};