Re: Pointers in const containers
On Jun 7, 1:45 pm, Adam Badura <abad...@o2.pl> wrote:
Lets consider following (typical as I think) code:
class tree_node {
public:
typedef std::vector< tree_node* > children_vector;
const children_vector& get_children() const { return children_; }
children_vector& get_children() { return children_; }
const tree_node* get_parent() const { return parent_; }
tree_node* get_parent() { return parent_; }
private:
children_vector children_;
tree_node* parent_;
};
There is an obvious problem of constness. Lets say we have a variable
"p_node" of type "const tree_node*". The pointer is to a const object
so we would except the object not being modified using this pointer
(compiler ought to check that). But as it is not possible to write:
p_node->get_children().clear()
since get_children returns const reference it is possible to do
following:
p_node->get_children().front()->do_something_non_const();
p_node->get_children().back() = new tree_node();
p_node->get_children().front()->get_parent()->do_something_non_const();
The const-ness of a container is orthogonal to the const-ness of the
objects referenced by its contents. In this case, the fact that
tree_node::get_children() returns a const std::vector of tree_node
pointers does not mean that those pointers point to const tree_node
objects. On the contrary, if the pointers in the vector point to const
tree_node objects, then tree_node::get_children() has to return a:
const std::vector<const tree_node*>&
instead of the vector of pointers to non-const tree_node object that
it currently returns.
This should not be possible for a const tree_node.
The program in this example does not modify the tree_node object
through the "pnode" pointer - but through (non-const) tree_node
pointer to the same object. In other words, although the program may
not use pnode to modify a particular tree_node object - there is
nothing that prohibits the program from modifying that same object
through a pointer to a non-const tree node object - should one happen
to exist..
Therefore, in order to prevent a tree_node object from being modified,
the program has to ensure that the tree_node object is not referenced
by a pointer to a non-const tree object - including those tree_node
pointers found in the std::vector that tree_node::get_children()
returns to its caller.
How to solve this problem?
I already came to two solutions:
1) Do not return the container, but add functions like
"children_begin" and "children_end" and define iterators so that the
will be const or non-const as appropriate. ...
2) Make tree_node behave like it was a container of "tree_node*"...
3) Have tree_node::get_children() return a reference to a const
std::vector<const tree_node*> (as described above) when called with a
const tree_node object.
Greg
--
[ See http://www.gotw.ca/resources/clcm.htm for info about ]
[ comp.lang.c++.moderated. First time posters: Do this! ]