Path: utzoo!utgpu!news-server.csri.toronto.edu!cs.utexas.edu!swrinde!zaphod.mps.ohio-state.edu!rpi!batcomputer!theory.tn.cornell.edu!lijewski From: lijewski@theory.tn.cornell.edu (Mike Lijewski) Newsgroups: comp.std.c++ Subject: Re: Default copy constructor not making a copy Keywords: cfront g++ copy constructor Message-ID: <1991Feb27.141337.23826@batcomputer.tn.cornell.edu> Date: 27 Feb 91 14:13:37 GMT References: <253@blsouth.UUCP> Sender: news@batcomputer.tn.cornell.edu Organization: Cornell National Supercomputer Facility Lines: 84 Nntp-Posting-Host: theory.tn.cornell.edu In article <253@blsouth.UUCP> klein@blsouth.UUCP (Michael Klein) writes: > >Can someone explain why the two classes defined below exhibit different >behavior? The class without the default copy constructor does not make >a copy of the *this argument for the + operator. There is a related >comment in Ellis & Stroustrup (12.6.1): "Had no copy constructor been >declared...all would have happened exactly as before because a copy >constructor would have been generated. Again, a good compiler would >eliminate the use of the generated copy constructor." I'm not convinced >that this statement applies in this case. Any enlightenment on this >subject would be welcome. I'm using ATT C++ 2.0 on a Sparc. > > >#include >#include > >class NoCopy { >public: > int x; > NoCopy (int a) { x = a; }; > NoCopy &operator +=(int a) { x += a; return *this; }; > NoCopy operator + (int a) { return NoCopy(*this) += a; }; >}; Replacing the line NoCopy operator + (int a) { return NoCopy(*this) += a; }; with NoCopy operator + (int a) { NoCopy tmp = *this; return tmp += a; }; you will get what you expected. This could be taken to be a bug, but I'm inclined to think that it's just another grey area in the language which is best avoided. No where in E&S is there any example or text that I can find which states that one can explicitely call a copy constructor which the compiler generates for you. My understanding is that if you make use of a construct which requires a copy constructor, the "right thing" will be done, where the "right thing" is a bitwise copy. It is interesting to note that when I tried the original code with g++, I got an error to the effect that the argument in `NoCopy(*this)' is wrong - g++ was expecting an int since the only constructor which had been defined was NoCopy::Nocopy(int). Seemingly g++ doesn't allow one to explicitely call a copy constructor which you haven't explicitely defined. I would suggest that this is the more correct behavior. Certainly it is better than silently allowing the construct and then doing the wrong thing. >class Copy { >public: > int x; > Copy(const Copy &c) : x(c.x) {}; > Copy (int a) { x = a; }; > Copy &operator =(int a) { x = a; return *this; }; > Copy &operator +=(int a) { x += a; return *this; }; > Copy operator + (int a) { return Copy(*this) += a; }; >}; > >void main() >{ > NoCopy xNo(1), xNo2(-1); > Copy xYes(2), xYes2(-2); > cout << "No=" << xNo.x << " Yes=" << xYes.x << endl; > cout << "No2=" << xNo2.x << " Yes=" << xYes2.x << endl; > xNo2 = xNo + 2; > xYes2 = xYes + 2; > cout << "No=" << xNo.x << " Yes=" << xYes.x << endl; > cout << "No2=" << xNo2.x << " Yes=" << xYes2.x << endl; >} > >Output of the program: >No=1 Yes=2 >No2=-1 Yes=-2 >No=3 Yes=2 >No2=3 Yes=4 -- Mike Lijewski (H)607/272-0238 (W)607/254-8686 Cornell National Supercomputer Facility ARPA: mjlx@eagle.cnsf.cornell.edu BITNET: mjlx@cornellf.bitnet SMAIL: 25 Renwick Heights Road, Ithaca, NY 14850