0

I want to store vertices data of a mesh in a class. Each instance has an array of floats and is accessible via a getter that returns the array pointer. The data of the array should be const, as well as the array itself. So my first thought was to declare the member this way:

const float * const m_vertices;  // const pointer to const floats

the problem is that the actual data is not know at compile time (loaded from a file, procedurally generated...)

Is there a way to ensure the data will be left untouched except when it's initialized (in the constructor for instance)?

EDIT : I tried what joseph proposed :

//Mesh class
Mesh::Mesh(const float *vertices)
: m_vertices(vertices)
{
}

//creation of data
int size = 10; //this can't be const because the number of vertices is not known at compile time 
float arr[size]; //error : "size" is not const
for (int i = 0; i < 10; i++) {
    arr[i] = i;
}
Mesh m = Mesh(arr); //this apparently works... But the constructor is expecting a const float *. Here i'm giving a float *. Why does this works ?
9
  • 1
    Make your "getter" a const member of a class, and the actual pointer or array a private member that can be initialised at run time (e.g. in the constructor of the class). Ensure you don't provide any other non-const function that provides access to the data. Also, you'll probably need t means of storing the number of elements, and accessing that number. Commented Jan 2, 2020 at 4:09
  • That was the alternative I thought of. But nothing prevents the data to be modified as the getter will return a float * and not a const float * Commented Jan 2, 2020 at 4:37
  • Then return a const float *. That prevents changing the data. Commented Jan 2, 2020 at 4:45
  • EDIT : Ok nevermind, you can return a const float * even though the underlying data is not const ? I have a lot of trouble understanding how the const keyword works tbh Commented Jan 2, 2020 at 4:47
  • A const float * effectively tells the compiler that the pointed-to float (or floats) should not be modified. A float * tells the compiler that modifying the float data is permitted. Now, taking a float * and adding a proviso of "shall not modify" does no harm - so there is no need to prevent it. Going the other way (removing const) permits modification of something that should not be modified (i.e. stops the compiler diagnosing the attempt as an error). Commented Jan 2, 2020 at 5:13

2 Answers 2

2

You can use the exact type you want. The constructor is allowed to write data to a const field:

class Foo {
  public:
    const float *const m_vertices;
    Foo(const float *vertices) : m_vertices(vertices) {}
};

Although there's no guarantee here that the caller doesn't have a non-const pointer. If you want to protect against that, then you'd need to copy the data instead of just using the pointer.

Sign up to request clarification or add additional context in comments.

2 Comments

This is only delaying the problem. As I said, the actual data is not known at compile time. I can't create the constructor paramater at runtime.
Yes you can. Why wouldn't you be able to? Can you edit your question to show the code you tried to do that that didn't work?
0
Mesh::Mesh(const float *vertices): m_vertices(vertices)
{
}

float number = 3.141;  // e.g.
int size = 10;
const float *vertices = &number;  // e.g.

vertices_ptr = new float[ size ];


meshPtr = new Mesh( vertices_ptr);

access it by meshPtr-> ...

1 Comment

Might not need new here. Set up the scope correctly and std::vector will do the job.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.