I would like to ask a question about methods' const-correctness. Let me illustrate the situation.
class MyClass
{
public:
...
void DiscussedMethod() { otherClass->NonConstMethod(); }
private:
OtherClass *otherClass;
};
I have a class MyClass
which keeps a pointer to OtherClass
. In DiscussedMethod
it calls OtherClass::NonConstMethod
which modifies some visible data.
I would like to know, whether it would be a good practice to make the DiscussedMethod
const
(since it doesn't modify any member data)? Would it be a bad practice? Or is both fine?
What if the OtherClass
kept a pointer to the MyClass
and in NonConstMethod
modified some of the MyClass
' data (meaning that the MyClass
member data would change during the DiscussedMethod
call). Would it be a bad practice to make the DiscussedMethod
const
then?
As far as I've been able to find out, the const
on a method is mostly a code documenting thing, so I would probably lean toward to not making the DiscussedMethod
const
, but I would like to hear your opinions.
EDIT: Some replies take the into account whether the object pointed to by otherClass
is owned by the MyClass
object. This is not the case in the scenario I'm working with. Lets say that both objects exist independently side by side (with the ability to modify each other). I think this analogy describes my situation quite well.
For example consider something like doubly-linked list, where each element is a class that keeps pointer to its neighbours and member variable color
. And it has method MakeNeighboursRed
which changes the color
of its neighbours but doesn't affect the calling object's state itself. Should I consider making this method const
?
And what if there was some possibility that MakeNeighboursRed
would call neighbour's MakeNeighboursRed
. So in the end the state of the object for which MakeNeighboursRed
has been called originally would change as well.
And I would like to thank you all for your opinions :-)
A function becomes const when the const keyword is used in the function's declaration. The idea of const functions is not to allow them to modify the object on which they are called. It is recommended practice to make as many functions const as possible so that accidental changes to objects are avoided.
The const member functions are the functions which are declared as constant in the program. The object called by these functions cannot be modified. It is recommended to use const keyword so that accidental changes to object are avoided. A const member function can be called by any type of object.
The const qualifier on a member function means that you cannot modify non-mutable , non-static class data members.
const member functions may be invoked for const and non-const objects. non-const member functions can only be invoked for non-const objects. If a non-const member function is invoked on a const object, it is a compiler error.
If MyClass
owns the OtherClass
instance i wouldn't make DiscussedMethod
constant.
The same goes for classes, managing resources. I.e. the standard containers do not return non const references or pointers to the managed memory using const functions, although it would be "possible" (since the actual pointer holding the resource is not modified).
Consider
class MyClass
{
public:
bool a() const { return otherClass->SomeMethod(); }
void b() const { otherClass->NonConstMethod(); }
private:
OtherClass *otherClass;
};
void foo (MyClass const &x)
{
cout << boolalpha << x.a() << endl;
x.b(); // possible if b is a const function
cout << boolalpha << x.a() << endl;
}
The foo
could print two different values although an implementor of foo
would probably expect that two function calls on a const object will have the same behaviour.
For clarification:
The following is invalid according to the standard since the const version of operator[]
returns std::vector<T>::const_reference
which is a constant reference to the value type.
std::vector<int> const a = { /* ... */ };
a[0] = 23; // impossible, the content is part of the state of a
It would be possible if there was only one signature of this function, namely referece operator[] (size_t i) const;
, since the operation does not alter the internal pointers of the vector but the memory they point to.
But the memory, managed by the vector is considered to be part of the vectors state and thus modification is impossible through the const vector interface.
If the vector contains pointers, those pointer will still be unmodifiable through the public const vector interface, although the pointers stored in the vector may well be non const and it may well be possible to alter the memory they point to.
std::vector<int*> const b = { /* ... */ };
int x(2);
b[0] = &x; // impossible, b is const
*b[0] = x; // possible since value_type is int* not int const *
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With