Relay-Version: version B 2.10 5/3/83; site utzoo.UUCP Path: utzoo!mnetor!uunet!husc6!rutgers!sri-spam!mordor!lll-lcc!ames!hc!beta!cmcl2!phri!dasys1!wfp From: wfp@dasys1.UUCP (William Phillips) Newsgroups: comp.lang.c++ Subject: Re: Interesting "Feature" of C++ Message-ID: <1787@dasys1.UUCP> Date: Sat, 24-Oct-87 02:36:33 EST Article-I.D.: dasys1.1787 Posted: Sat Oct 24 02:36:33 1987 Date-Received: Tue, 27-Oct-87 01:44:28 EST References: <1718@dasys1.UUCP> <4513@spool.wisc.edu> Organization: The Big Electric Cat Lines: 92 Keywords: virtual functions, assigning to this Summary: aha! (Please note - my host's news editor just choked on this; I am trying to reconstruct what I was just wrapping up when it died.) In article <4513@spool.wisc.edu>, dave@spool.wisc.edu (Dave Cohrs) writes: > In article <1718@dasys1.UUCP> wfp@dasys1.UUCP (William Phillips) writes > about a problem with changing "this" in a constructor. > > Sorry, but I don't have a solution, but I have an even more painful > problem. If we take William's example and expand it a bit (I added > a constructor to "base": [example deleted] > Now, when you reassign "this", the base constructor gets called to > reinitialize the data. This is very harmful in two cases, if you set > this to nil, or if you set this to an allready allocated and > initialized object. > In the first case, if you say "this = 0" (yes, explicit assignments are > just as bad), or in any way set this to a nil pointer, base::base will > reallocate space for this and this in "derived" will not be nil after > the assignment. I'm not quite sure I understand what you're saying, but if you look at section 7.7 of , it is stated that an assignment to this in a derived class constructor will delay the execution of the base class constructor until after such assignment; I have been using this technique successfully to manipulate some data needed by the base class constructor within the derived class constructors; example: cnst::cnst(int i) : (s, "int", literal_t) { sprintf(s, "%d", i); // Force base class ctor to wait till sprintf done this = NULL; ic++; } which works fine to get s formatted the way I want it before calling cnst's base class constructor with s as an argument. > In the second case, say that you have a list of objects of type > "derived". Have the derived constructor search the list until it finds > an appropriate object, and then assigns this to that object. Once > again, the base constructor is called, possibly destroying all useful > data in the object. Aha! That may explain a particularly vexing problem I was wrestling with earlier this week. I was in fact searching a list, finding an appropriate object, and assigning this to it (er, from it, I think!). If the found object passed certain tests, it was modified slightly, but otherwise left alone; no problem. If it failed those tests but passed others, I created a new object of the same class and (thought) I left the original alone; however, I found that the new object was fine, but the original one had been stripped down to its base class and consequently lost all its extra derived class information (the virtual functions that printed out the contents and class of each object for debugging purposes saw the original object as a base object !) I _had_ had the impression from some earlier attempts and what I could glean from that once an object was constructed its class was cast in stone; apparently not so! In fact, the reason I was using the " this = NULL " technique above was because I had tried to construct a base class object and then "recast" it into a derived class object after the fact. Didn't work! > Actually, this behaviour is documented. See sec. 8.5.8 in the C++ book. > Think of the virtual table pointer as a member (albeit invisible) of > the object. Then, following the rules in 8.5.8, the table pointer > gets set after reassigning "this". Note that I saw no code to check > if this was set to nil in any case. If you look at the C code generated by cfront (if you can stomach it :-), you will see that the assignment this = NULL generates _auto_this = 0 ...and that's all whereas an "inexplicit" assignment of this (such as " this = funct() " ) additionally generates code to reassign the virtual table pointer, which will cause severe distress if the value of this is something weird like 0. P.S.: I have been told that is (a)incomplete and (b)full of errors; I believe it. It also doesn't have an index worth a damn. I _wish_ Harbison & Steele would do for C++ what they did for C. -- William Phillips {allegra,philabs,cmcl2}!phri\ Big Electric Cat Public Unix {bellcore,cmcl2}!cucard!dasys1!wfp New York, NY, USA (-: Just say "NO" to OS/2! :-)