如何防止修改数组数据?

问题描述 投票:4回答:1

说我有一个看起来像这样的类(这只是一个示例):

class A {
    double *ptr;
public:
    A() : ptr( new double[100] ) {}
    A( const A &other ) {
        other.ptr[7] = 15;
    }
    void doNotChangeMyData() const {
        ptr[43] = 14;
    }
    void changeMyData() {
        ptr[43] = 14;
    }
    ~A() { delete[] ptr; }
};

复制构造函数和const函数中的doNotChangeMyData都使之无法更改ptr;但是,这仍然允许我修改ptr指向的数组的内容。

是否有一种方法可以防止ptr数组的内容仅在const实例中被更改,而不能“小心”(或远离原始指针)?

我知道我可以做类似的事情

void doNotChangeMyData() const {
    const double *const ptr = this->ptr;
    ptr[43] = 14; // then this would fail to compile
}

但是我宁愿不必...

c++ const
1个回答
2
投票

指针不传播const。将const添加到类型double*会产生double* const,在取消引用时会导致非const左值。

相反,您可以使用std::vector

class A {
    std::vector<double> data(100);
public:
    // no explicit copy ctor or dtor
};

a std::array

class A {
    std::array<double, 100> data{};
public:
    // no explicit copy ctor or dtor
};

或内置数组(不推荐):

class A {
    double data[100] {};
public:
    // no explicit copy ctor or dtor
};

所有三个选项都传播const

如果您确实要使用指针(强烈建议不要使用),请至少使用std::unique_ptr以避免手动内存管理。您可以使用库基本原理2 TS中的std::experimental::propagate_const包装器:

class A {
    std::experimental::propagate_const<std::unique_ptr<double[]>> ptr;
public:
    A()
        : ptr{new double[100] {}}
    {
    }
    // manual copy ctor
    A(const A& other)
        : ptr{new double[100]}
    {
        std::copy_n(other.ptr.get(), 100, ptr.get());
    }
    // defaulted move ctor & dtor
    // assignment operator, etc.
    // ...
};

它尚未在标准中,但是许多编译器都支持它。当然,这种方法不如适当的容器。

© www.soinside.com 2019 - 2024. All rights reserved.