Topic: const structures...help please!


Author: clamage@Eng.Sun.COM (Steve Clamage)
Date: 1995/04/19
Raw View
In article s0u@ritz.cec.wustl.edu, jaf3@ritz.cec.wustl.edu (John Andrew Fingerhut) writes:
>I have a question about how const maps over to members of a structure
>particularly, members which are pointers.
>
>If I have a class X which contains a Y* member yp, and I have a const pointer
>to X (const X* xp),

Actually, this is a pointer to const X, not a const pointer.

>then am I allowed to change the Y to which xp->yp points?

Yes.

>I know that I cannot change xp->yp such that it points to another Y.  In
>otherwords, is the type of the expression:
> xp->yp
>Y* const or const Y*const?

The expression has type
 Y* const
meaning, as you say, that you cannot change yp (via xp), but you can
change the Y object that yp points to.

>
>The reason for the question is that if the answer is the former, then it
>renders const list pointers virtually meaningless.  For example, if I have
>a List class which contains a pointer to the head element, the abstraction
>is actually the List class and each Item that is linked together.  Having
>a const List *, prevents me from changing which item is at the head of the
>list (by preventing me from modifying head) but doesn't prevent me from
>reordering any of the other elements in the list nor from changing the
>contents of the elements themselves.

I don't see the problem. Here is a typical fragment of a list class:

class List {
 class Node { // private list node type
  T* data; // item on the list
  Node* next;
 };
public:
 void insert(T*, int); // non-const
 void delete(int); // non-const
 const T* operator[](int) const; // for const Lists
 T* operator[](int); // for non-const Lists
};

Now declare
 const List *p = ...
 p->insert(myT, 3); // error, const list
 p->delete(3);  // error, const list
 *(*p)[3] = ... ; // error, left side has type "const T"

Well, you wouldn't use subscripting with a pointer, but you get the idea.
For the last line, substitute
 const List& q = ...;
 *q[3] = ... ; // error, left side has type "const T"
or assume an "index" function instead of subscript notation.
 *(p->index(3)) = ... ; // error, left side has type "const T"

The point is that functions which operate on a const List should return
only values or pointer-to-const. In addition, you should not return
pointers to the local Node class which keeps track of the link.

Perhaps you have an "intrusive list", where the "next" pointer is in the
object, instead of being in the List class. You then don't have the
right abstraction to support both const and non-const lists.

---
Steve Clamage, stephen.clamage@eng.sun.com







Author: fenster@ground.cs.columbia.edu (Sam Fenster)
Date: 1995/04/19
Raw View
jaf3@ritz.cec.wustl.edu (John Andrew Fingerhut) writes:
> If I have a class X which contains a Y* member yp, and I have a const
> pointer to X (const X* xp), then am I allowed to change the Y to which
> xp->yp points?

It's not clear that this question belongs in comp.std.c++, which is meant for
discussion of the forthcoming ISO/ANSI C++ standard, but I'll answer it
anyway:  Yes, you are allowed to change the Y:

   struct Y {int i;} y;
   struct X {Y *yp;  X (Y &y) {yp=&y;}} x(y), const *cxp=&x;
   cxp->yp->i = 0;

> The reason for the question is that if the answer is the former, then it
> renders const list pointers virtually meaningless.

No.  You can overload accessor member functions on constness:

   struct Y {int i;} y;
   class X {
      Y *private_yp;
   public:
      X (Y &y) {private_yp=&y;}
      Y *yp () {return private_yp;}
      Y const *yp () const {return private_yp;}
   } x(y), *xp=&x, const *cxp=&x;
   xp->yp()->i = 0;       // Allowed by compiler
   cxp->yp()->i = 0;      // Not allowed by compiler
   int i = cxp->yp()->i;  // Allowed by compiler





Author: jaf3@ritz.cec.wustl.edu (John Andrew Fingerhut)
Date: 1995/04/19
Raw View
I have a question about how const maps over to members of a structure
particularly, members which are pointers.

If I have a class X which contains a Y* member yp, and I have a const pointer
to X (const X* xp), then am I allowed to change the Y to which xp->yp points?
I know that I cannot change xp->yp such that it points to another Y.  In
otherwords, is the type of the expression:
 xp->yp
Y* const or const Y*const?

The reason for the question is that if the answer is the former, then it
renders const list pointers virtually meaningless.  For example, if I have
a List class which contains a pointer to the head element, the abstraction
is actually the List class and each Item that is linked together.  Having
a const List *, prevents me from changing which item is at the head of the
list (by preventing me from modifying head) but doesn't prevent me from
reordering any of the other elements in the list nor from changing the
contents of the elements themselves.

By the way, SUN C++ 4.0 and a couple of cfront compilers that I have don't
complain about xp->yp->ymember =, implying that the answefr is Y* const.

--
Stephen Gevers
sg3235@shelob.sbc.com