 |
C++Talk.NET C++ language newsgroups
|
| View previous topic :: View next topic |
| Author |
Message |
Dave Guest
|
Posted: Thu Dec 25, 2003 7:10 am Post subject: How does the destructor get called? |
|
|
Hello all,
When I run the program below, I see this output:
base::base() 42
derived::derived() 42
derived::~derived() 42
base::~base() 42
This is, of course, correct. However, I don't understand how the derived
class destructor is getting called. I have a const reference to *base* that
is referring to a derived object. Is this not akin to having a pointer to
base pointing to a derived object, where you would expect the derived class
destructor to get called only if the base class destructor is virtual?
Thanks,
Dave
#include <iostream>
class base
{
public:
base(int d): base_data(d)
{
std::cout << "base::base() "
<< base_data
<< std::endl;
}
base(const base &other): base_data(other.base_data)
{
std::cout << "base::base(const base &) "
<< base_data
<< std::endl;
}
~base()
{
std::cout << "base::~base() "
<< base_data
<< std::endl;
}
private:
int base_data;
};
class derived: public base
{
public:
derived(int d): base(d), derived_data(d)
{
std::cout << "derived::derived() "
<< derived_data
<< std::endl;
}
derived(const derived &other): base(other),
derived_data(other.derived_data)
{
std::cout << "derived::derived(const derived &) "
<< derived_data
<< std::endl;
}
~derived()
{
std::cout << "derived::~derived() "
<< derived_data
<< std::endl;
}
private:
int derived_data;
};
int main()
{
const base &r = derived(42);
(void) r; // Suppress compiler warning
}
[ See http://www.gotw.ca/resources/clcm.htm for info about ]
[ comp.lang.c++.moderated. First time posters: Do this! ]
|
|
| Back to top |
|
 |
Jonathan Turkanis Guest
|
Posted: Thu Dec 25, 2003 2:39 pm Post subject: Re: How does the destructor get called? |
|
|
"Dave" <better_cs_now (AT) yahoo (DOT) com> wrote:
| Quote: | When I run the program below, I see this output:
base::base() 42
derived::derived() 42
derived::~derived() 42
base::~base() 42
This is, of course, correct. However, I don't understand how the derived
class destructor is getting called. I have a const reference to *base*
that
is referring to a derived object.
int main()
{
const base &r = derived(42);
(void) r; // Suppress compiler warning
}
|
The expression 'derived(42)' creates a temporary object of type derived
which is bound to the reference r. This temporary object persists for the
lifetime of r (12.2 paragraph 5). When the reference goes out of scope, the
temporary's destructor is called (12.2 paragraph 3).
Jonathan
[ See http://www.gotw.ca/resources/clcm.htm for info about ]
[ comp.lang.c++.moderated. First time posters: Do this! ]
|
|
| Back to top |
|
 |
Francis Glassborow Guest
|
Posted: Thu Dec 25, 2003 2:40 pm Post subject: Re: How does the destructor get called? |
|
|
In message <vukl5ff4htil16 (AT) news (DOT) supernews.com>, Dave
<better_cs_now (AT) yahoo (DOT) com> writes
| Quote: | When I run the program below, I see this output:
base::base() 42
derived::derived() 42
derived::~derived() 42
base::~base() 42
This is, of course, correct. However, I don't understand how the derived
class destructor is getting called. I have a const reference to *base* that
is referring to a derived object. Is this not akin to having a pointer to
base pointing to a derived object, where you would expect the derived class
destructor to get called only if the base class destructor is virtual?
Thanks,
Dave
#include
instrumented base and derived classes snipped
int main()
{
const base &r = derived(42);
|
At this point you have a temporary derived whose life has been extended
by binding it to a const reference. However the compiler is responsible
for the eventual destruction of that temporary when r goes out of scope;
it fulfils its responsibility.
| Quote: | (void) r; // Suppress compiler warning
}
|
Note that this program exposes the lack of virtual dtors:
int main(){
base * b_ptr = new derived;
// the use of 'new' makes the programmer responsible for the
// correct destruction of the object
delete b_ptr;
// and the compiler will use the static (compile time) type of b_ptr
// to select the base dtor because of the lack of virtual
}
--
Francis Glassborow ACCU
Author of 'You Can Do It!' see http://www.spellen.org/youcandoit
or http://www.robinton.demon.co.uk
Happy Xmas, Hanukkah, Yuletide, Winter/Summer Solstice to all.
[ See http://www.gotw.ca/resources/clcm.htm for info about ]
[ comp.lang.c++.moderated. First time posters: Do this! ]
|
|
| Back to top |
|
 |
Siemel Naran Guest
|
Posted: Thu Dec 25, 2003 2:43 pm Post subject: Re: How does the destructor get called? |
|
|
"Dave" <better_cs_now (AT) yahoo (DOT) com> wrote in message
| Quote: | base::base() 42
derived::derived() 42
derived::~derived() 42
base::~base() 42
This is, of course, correct. However, I don't understand how the derived
class destructor is getting called. I have a const reference to *base*
that
is referring to a derived object. Is this not akin to having a pointer to
base pointing to a derived object, where you would expect the derived
class
destructor to get called only if the base class destructor is virtual?
int main()
{
const base &r = derived(42);
(void) r; // Suppress compiler warning
}
|
The expression "derived(42)" creates a temporary derived object which must
eventually be destroyed.
The lhs "const base& r =" binds the temporary to a reference.
The next line (void)r has no effect.
At the end of the function block, variable r is not destroyed because it is
a reference.
However, the temporary derived(42) is destroyed, and that explains the
output you see.
Had variable been an object, things would be different.
int main()
{
const base r = derived(42);
(void) r; // Suppress compiler warning
}
The output of this program should I think be
base::base() 42
derived::derived() 42
base::base(const base&) 42 // from copying 'r'
derived::~derived() 42 // from deleting temporary
base::~base() 42 // finishing deleting temporary
base::~base() 42 // from deleting 'r'
--
+++++++++++
Siemel Naran
[ See http://www.gotw.ca/resources/clcm.htm for info about ]
[ comp.lang.c++.moderated. First time posters: Do this! ]
|
|
| Back to top |
|
 |
Conrad Weyns Guest
|
Posted: Thu Dec 25, 2003 5:38 pm Post subject: Re: How does the destructor get called? |
|
|
"Dave" <better_cs_now (AT) yahoo (DOT) com> wrote
| Quote: |
Hello all,
When I run the program below, I see this output:
base::base() 42
derived::derived() 42
derived::~derived() 42
base::~base() 42
This is, of course, correct. However, I don't understand how the derived
class destructor is getting called. I have a const reference to *base*
that
is referring to a derived object. Is this not akin to having a pointer to
base pointing to a derived object, where you would expect the derived
class
destructor to get called only if the base class destructor is virtual?
|
The object is not getting destroyed through the reference - as would be to
case when deleting a derived through a pointer to base. In you example, it
is a temporary object (a complete derived) that is getting auto-detroyed.
Having "assigned" it to a const base& only forces its life time to be
extended to the lifetime of the reference. When a reference goes out of
scope, there can be no implicit destruction of the object it is referencing.
Conrad Weyns.
[ See http://www.gotw.ca/resources/clcm.htm for info about ]
[ comp.lang.c++.moderated. First time posters: Do this! ]
|
|
| Back to top |
|
 |
Ulrich Eckhardt Guest
|
Posted: Thu Dec 25, 2003 5:38 pm Post subject: Re: How does the destructor get called? |
|
|
Dave wrote:
| Quote: | When I run the program below, I see this output:
base::base() 42
derived::derived() 42
derived::~derived() 42
base::~base() 42
int main()
{
const base &r = derived(42);
(void) r; // Suppress compiler warning
}
|
You should insert another few debug-staements into main to also see when
exactly the thing is destroyed. Anyhow, the rule is that if a temporary is
bound to a const reference, its lifetime is extended to the scope of the
reference. And that is all you see. If you hadn't bound it to a const
reference, it would have been just the same, only the 'when' would have
changed.
For some clever uses of this, see e.g.
http://www.cuj.com/documents/s=8250/cujcexp2106alexandr/
Uli
--
Questions ?
see C++-FAQ Lite: http://parashift.com/c++-faq-lite/ first !
[ See http://www.gotw.ca/resources/clcm.htm for info about ]
[ comp.lang.c++.moderated. First time posters: Do this! ]
|
|
| Back to top |
|
 |
Peter Koch Larsen Guest
|
Posted: Thu Dec 25, 2003 5:39 pm Post subject: Re: How does the destructor get called? |
|
|
"Dave" <better_cs_now (AT) yahoo (DOT) com> skrev i en meddelelse
news:vukl5ff4htil16 (AT) news (DOT) supernews.com...
| Quote: |
Hello all,
When I run the program below, I see this output:
base::base() 42
derived::derived() 42
derived::~derived() 42
base::~base() 42
This is, of course, correct. However, I don't understand how the derived
class destructor is getting called. I have a const reference to *base*
that
is referring to a derived object. Is this not akin to having a pointer to
base pointing to a derived object, where you would expect the derived
class
destructor to get called only if the base class destructor is virtual?
Thanks,
Dave
|
[snip]
| Quote: | int main()
{
const base &r = derived(42);
(void) r; // Suppress compiler warning
}
|
Hi Dave
Nothing weird is going on. When r (a REFERENCE to a class) is bound to the
temporary derived object, the rule is that the lifetime of that object
should be as long as the lifetime of r. Please note that there is no base
object around, except for the one that is part of the derived object.
Kind regards
Peter
[ See http://www.gotw.ca/resources/clcm.htm for info about ]
[ comp.lang.c++.moderated. First time posters: Do this! ]
|
|
| Back to top |
|
 |
|
|
You cannot post new topics in this forum You cannot reply to topics in this forum You cannot edit your posts in this forum You cannot delete your posts in this forum You cannot vote in polls in this forum
|
|