Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How to prevent modification to array data?

Tags:

c++

constants

Say I have a class that looks like this (this is just an example):

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; }
};

The const in both the copy constructor and the doNotChangeMyData function make it so that ptr cannot be changed; however, this still allows me to modify the contents of the array pointed to by ptr.

Is there a way to prevent the contents of ptr's array from being changed in const instances only, short of "being careful" (or changing away from raw pointer)?

I know I could do something like

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

But I'd rather not have to ...

like image 289
ChrisMM Avatar asked Dec 10 '19 12:12

ChrisMM


People also ask

Does array reduce modify original array?

JavaScript Array reduce() The reduce() method does not change the original array.

Can arrays be edited?

Array is a local variable inside both main and change . Its address is passed from main to change . After that, change can reassign it and it will have no effect on the array in main .

How to prevent array mutation in JS?

In this article, we will go through some common techniques to help you become familiar with how to prevent array mutation in JS. 1. Spread Operator 2. Array’s Slice () method 3. JSON-serializable content 1. Add Item to Array 2. Add Item At Index 3. Conditionally Add Item to Array 1. Delete Last Item from Array 2. Delete Item At Index 1.

How to avoid changes to an array in C++?

The only way to avoid changes to an array is to not share the reference to the array with other code that might change it. In your example, you have what is known as a leaky abstraction.

How to prevent modification of object in JavaScript?

How to prevent modification of object in JavaScript ?. ECMAScript 5 has introduced several methods to prevent modification of object. Those preventive measures ensures that no one, accidentally or otherwise change functionality of object. In this level, one cannot add any new properties or methods but can access existing properties or methods.

How to prevent an array from changing state in Java?

To prevent changing the state of a particular object, you should mark it's field as final. There is no such thing as immutable (unchangeable) array in Java. The Java language does not support this.


1 Answers

Pointers do not propagate const. Adding const to the type double* yields double* const, which results in a non-const lvalue when dereferenced.

Instead, you can use a 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
};

or a builtin array (not recommended):

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

All of the three options propagate const.

If you really want to use pointers (not recommended), consider using a std::unique_ptr to avoid manual memory management. You can use the std::experimental::propagate_const wrapper from the library fundamentals 2 TS: (using raw arrays with unique_ptr has some complications, as mentioned in a comment below)

#include <array>
#include <memory>
#include <experimental/propagate_const>

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

It's not in the standard yet, but many compilers support it. Of course, this approach is inferior to the proper containers.

like image 185
L. F. Avatar answered Oct 07 '22 18:10

L. F.