Reputation: 2721
Apparently, a const member function is still allowed to change data that the class member are pointing to. Here's an example of what I mean:
class MyClass
{
public:
MyClass();
int getSomething() const;
private:
int* data;
};
// ... data = new int[10];, or whatever
int MyClass::getSomething() const
{
data[4] = 3; // this is allowed, even those the function is const
return data[4];
}
I'd prefer if this was not allowed. How should I define "data" so that "getSomething() const" isn't allowed to change it? (but so that non-const functions are allowed to change it.) Is there some kind of "best practice" for this? Perhaps std::vector?
Upvotes: 5
Views: 1762
Reputation: 361802
In a const
member function, the type of data
changes from int*
to int *const
:
int * const data;
which means, it's the pointer which is const
in the const member function, not the data itself the pointer points to. So you cannot do the following:
data = new int[100]; //error
as it's attempting to change the pointer itself which is const, hence disallowed, but the following is allowed:
data[0] = 100; //ok
Because changing the content doesn't change the pointer. data
points to same memory location.
If you use std::vector<int>
, then you can achieve what you want. In fact, vector solves this problem, along with the memory management issues, therefor use it:
class MyClass
{
public:
MyClass();
int getSomething() const;
private:
std::vector<int> data;
};
MyClass::MyClass() : data(10) {} //vector of size 10
int MyClass::getSomething() const
{
data[4] = 3; // compilation error - this is what you wanted.
return data[4];
}
Avoid non-RAII design as much as you can. RAII is superior solution to memory management issues. Here, with it, you achieve what you want. Read this:
Upvotes: 7
Reputation: 258678
The reason you should use std::vector is actually because you want to store a collection of ints, and not an int pointer, so why not use it?
It would also solve your const'ness issue.
Here's how it works: declaring a method const will make all class members const. In your case, that means that in the method scope, your member data
will become a constant pointer to an int. That means you can change the int (also meaning array members) as long as data
points to the same location. Using std::vector
, data would become a const std::vector
, on which you could only call const functions. So yes, you should use std::vector
.
Upvotes: 4
Reputation: 81409
There is no way to do what you want. Your const member function can't change the value of data (the address it points to), but there is nothing about not changing the contents it points to as you have already noticed. Using a std::vector
would help, since within a const member function you would actually have a const vector, not being able to call any of its mutable functions.
Upvotes: 4