Path: utzoo!mnetor!tmsoft!torsqnt!lethe!yunexus!ists!helios.physics.utoronto.ca!news-server.csri.toronto.edu!bonnie.concordia.ca!uunet!zaphod.mps.ohio-state.edu!think.com!hsdndev!husc6!ngo From: ngo@tammy.harvard.edu (Tom Ngo) Newsgroups: comp.std.c++ Subject: Responses to ~const 1.6: Experience? Message-ID: Date: 19 Feb 91 16:45:31 GMT Sender: news@husc6.harvard.edu Distribution: comp Organization: Harvard Chemistry Department Lines: 85 Background information to this posting was in a very recent summary. A proposed extension to C++ is much more credible if one can cite past experience with it. Obviously nobody has yet put ~const into a compiler and tried it out. However, many people have had the need to use the equivalent of both ~const data members and member functions. It is experience of this sort that I would like to solicit. Under what circumstances have you had to cast away constness? What problems have you run into? Do you abide by some coding convention? And a specific question: would it really be necessary to allow ~const member functions, or are all needs covered by ~const data? Let me kick off the discussion by describing a few categories of applications, then giving an example of the convention that I have used as a workaround to not having ~const. (1) Application: I have needed to cast away constness when I have wanted to change an object's representation without changing its meaning. Examples: * Self-resizing array. When I got past the bounds of the existing array I would call a private method grow(), which would allocate new memory and copy contents as necessary. Calls for a ~const member function; see item (2) below. * Iterator. An iterator might be a pair of methods init() and next() designed to be used like this: const A obj; // container class of some kind obj.init(); while( obj.next() ) { ... } Here, I would either make the methods init() and next() ~const, or I would make the data members that record the state of the iterator ~const. * Internal buffer. I have a Trie class which represents a collection of strings. When I want to retrieve any one of those strings, I need to write the result to a character buffer. I want the user to be able to retrieve a string from a const Trie, but do not want him or her to have to worry about allocating the memory for the character buffer. Answer: a ~const character buffer within the class. (Incidentally, it must be resizable.) * Cache or secondary representation. This is a trumped-up example, because my real example is too application-specific. Say you have an array class A. Based on your intended usage, you have decided it is best to store the elements in unsorted form. But occasionally (very rarely) you will want to know the i'th, j'th and k'th element of some const A. So you have decided to do some kind of sort, but only when it is needed. It is appropriate to store the order information in ~const data members. (2) Example of the convention I have used as a workaround: Here is what I do now to implement ~const member functions-- void DynArray::grow() const { DynArray *const auxthis = (DynArray *const) this; // refer to all data through auxthis } The method is const because I want to be able to invoke it on a const object. Here const signfifies that the object's meaning is unchanged by the method. (The use of the word "auxthis" is historical. Originally, instead of ~const I had proposed the addition of a new keyword "auxiliary" before Tony Hansen pointed out that this would break existing code.) Here is what I would do if I had ~const-- void DynArray::grow() ~const { ... } I don't have a corresponding convention for ~const data members. -- Tom Ngo ngo@harvard.harvard.edu 617/495-1768 lab number, leave message