From: "John Bodfish" Newsgroups: comp.os.msdos.djgpp Subject: Re: Calling Class Constructors and Destructors Date: 12 Feb 1998 19:19:11 GMT Organization: Ameritech Library Services Lines: 102 Message-ID: <01bd37ea$863f1d00$b8cde7c0@JOHNB.als.ameritech.com> References: <34df6b1d DOT 3108479 AT news DOT easynet DOT co DOT uk> NNTP-Posting-Host: n5184.als.ameritech.com To: djgpp AT delorie DOT com DJ-Gateway: from newsgroup comp.os.msdos.djgpp Precedence: bulk Geoffrey French wrote in article <34df6b1d DOT 3108479 AT news DOT easynet DOT co DOT uk>... > I have a bit of a strange problem with DJGPP : ... code sample snipped.... > I find that upon calling the constructor TC(long i) in the line 'x = > TC(1)' not only is the constructor called, but the destructor is > called straight afterwards (!), thus deleteing the reserved memory for > the variable a. However, in the line 'y = new TC(1)' only the > constructor is called. It seems that whenever you say 'c = > TClass(...)' the TClass destructor is called as well as the > constructor. > > Can anyone help? > > Thanx in advance > > -Geoffrey French Your statement: > It seems that whenever you say 'c = > TClass(...)' the TClass destructor is called as well as the > constructor. is right. Many find this surprising, because they aren't clear on the meaning of the statement "x = TC(1);". Here's my attempt at clarification: This line: > TC x, *y; means "Construct an instance of the TC class (using default constructor) named "x", and construct a pointer to an object of the TC class." So your TC::TC() gets called there for the 'x' object. Then the line: > x = TC(1); means "Construct a (unnamed) temporary instance of the TC class (using the TC(long i) constructor) and then assign its value (using the default operator= which the compiler created for you) to the instance of the TC class named 'x'. After the assignment deconstruct the (unnamed) temporary instance of the TC class." This is where your destructor is getting called: on the (unnamed) temporary instance of the TC class. Meanwhile, x.a is still valid. Surprised? You probably thought this statement meant "Construct an instance of the TC class (using the TC(long i) constructor) named 'x'." If you simply want to construct 'x' with x.a == 1, then change the line TC x, *y; to TC x(1), *y; which means "Construct an instance of the TC class (using the TC(long i) constructor) named 'x', and construct a pointer to an object of the TC class named 'y'." Then you don't need the line x = TC(1); as 'x' already has member 'a' set to '1'. On the other hand, if you really want to change the value of 'x' with an assignement statement, then you can: a) accept that a temporary TC object be constructed/destructed so that the compiler can use the assignment operator. b) create an assignment operator which changes the value of x.a, such as: "TC::operator=(long i) { a = i; }" Advantage: avoids the temporary. Disadvantage: If class TC has many members which you need to change in this assignment operator, then the function parameter "long i" needs to be a class/struct itself, which means.... back to construction of a temporary just to change 'x'. c) write a "TC::change(long i)" function which changes the value of x.a. Advantage: you can change several members at once: class TC { long a; char* my_name; TC::change(long i, char* name) { a = i; my_name = name; } }; Disadvantage: your calls of this function are explicit: x.change(3, "foo"); You can't do: x = (3, "foo"); That might not be a disadvantage.... (I realize your code is just an illustration but) Did you know that the memory allocated by "y = new TC(1)" isn't freed because you don't have a "delete y;" statement? If you add that, you'll see the TC destructor get called for the object pointed to by 'y' also. I hope this helps. -- John Bodfish bodfish AT als DOT ameritech DOT com