Reputation: 10539
Suppose we have class for linked list of T. (I don't know if code actually works)
template <typename T>
struct List{
struct Node{
T data;
Node *next;
};
// add, remove etc...
Node *locate(const T &a) const{
for(Node *node = head; node; node = node->next)
if (node->data == a)
return node;
return nullptr;
}
private;
Node *head;
};
If you inspect method locate
, it basically can harm and ruin the linked list, even the method is marked as const
.
I just noticed something else. Since Node is not const, Node::data can be changed as well.
Supposing this was programmer mistake, is there a C++ way this to be avoid?
I know the method can be written as this.
const Node *locateConst(const T &a) const{ for(const Node *node = head; node; node = node->next) if (node->data == a) return node; return nullptr; }
Upvotes: 1
Views: 57
Reputation: 4201
You are seeking an experimental feature, yet unavailable on many platforms. If your std libray supports, you can use std::experimental::propagate_const<node*>
instead of naked raw pointers.
https://en.cppreference.com/w/cpp/experimental/propagate_const
In the mean time, you can implement your - maybe less generic - own version.
Upvotes: 1
Reputation: 11102
In C++, "const" means "can't change this object", it does NOT mean "can't change things this object points to".
I.e. with const List *const_list
you can't change const_list->head
, but you can change const_list->head->next
or const_list->head->data
.
If you're writing a List class, then you probably want const List
to mean "can't change things this object points to", and C++ provides the tools you need to implement List so it works that way. But it's your job, as the author of the List class, to do that - the compiler can't just magically know that's what you intended.
Upvotes: 0
Reputation: 25388
is there a C++ way this to be avoid?
No, of course not. Programmers do have responsibilities you know. The way the method is declared promises not to change head
, not *head
.
Upvotes: 0