By using this site, you agree to our updated Privacy Policy and our Terms of Use. Manage your Cookies Settings.
446,148 Members | 1,342 Online
Bytes IT Community
+ Ask a Question
Need help? Post your question and get tips & solutions from a community of 446,148 IT Pros & Developers. It's quick & easy.

Virtual destructors and the C++ standard.

P: n/a
I was recently surprised about how a chunk of code compiled and
executed, which lead me to wonder what would be "correct" from a C++
standards perspective. (I don't need help to arrive at sensible code,
this is for academic interest only...)

--
#include <iostream>
using namespace std;
class A {
public:
A() { cerr << "CA"; }
virtual ~A() =0; };
class B : public A {
public:
B(bool a) { if (a) throw a; }
~B() { cerr << "DA"; } };
int main(int c,char *v[])
{
try { B b(c==1); } catch(bool x) { cerr << "catch" << endl; }
return 0;
}
--
I'm interested to know:
* While this obviously compiles, is it complete - i.e. should it link?
* Should the fact that A has a pure virtual destructor influence
whether or not B's destructor is called in the context of exception
'a'?
* Have either of the above two questions different answers if one
looks from the perspective different C++ standards vintages?

Jun 10 '07 #1
Share this Question
Share on Google+
2 Replies


P: n/a
gg***********@shic.co.uk wrote:
I was recently surprised about how a chunk of code compiled and
executed, which lead me to wonder what would be "correct" from a C++
standards perspective. (I don't need help to arrive at sensible code,
this is for academic interest only...)

--
#include <iostream>
using namespace std;
class A {
public:
A() { cerr << "CA"; }
virtual ~A() =0; };
class B : public A {
public:
B(bool a) { if (a) throw a; }
~B() { cerr << "DA"; } };
int main(int c,char *v[])
{
try { B b(c==1); } catch(bool x) { cerr << "catch" << endl; }
return 0;
}
--
I'm interested to know:
* While this obviously compiles, is it complete - i.e. should it link?
* Should the fact that A has a pure virtual destructor influence
whether or not B's destructor is called in the context of exception
'a'?
* Have either of the above two questions different answers if one
looks from the perspective different C++ standards vintages?
According to my understanding it should not link. After class B's
destructor executes, it calls class A's destructor (see 12.4.6).
Because you've declared a destructor in class A, the implicit destructor
is not created for you (see 12.4.3). You did not define A's destructor
anywhere, so when you try to link, the call to it in B's destructor will
be unresolved.

Making a member function pure virtual, by the way, does NOT mean that
you cannot provide an implementation (see 10.3.8). It only imposes the
requirement that child classes must override the member function, and
that no instances of the class containing the pure virtual member
function may be created.

The solution? Provide a definition for A's destructor. This cannot be
done in a declaration (see note in 10.4.2), so add the following line
somewhere before main:
A::~A() {}

--
Alan Johnson
Jun 10 '07 #2

P: n/a
On Jun 10, 7:03 am, ggroups_st...@shic.co.uk wrote:
I was recently surprised about how a chunk of code compiled and
executed, which lead me to wonder what would be "correct" from a C++
standards perspective. (I don't need help to arrive at sensible code,
this is for academic interest only...)
--
#include <iostream>
using namespace std;
class A {
public:
A() { cerr << "CA"; }
virtual ~A() =0; };
class B : public A {
public:
B(bool a) { if (a) throw a; }
~B() { cerr << "DA"; } };
int main(int c,char *v[])
{
try { B b(c==1); } catch(bool x) { cerr << "catch" << endl; }
return 0;}
--
I'm interested to know:
* While this obviously compiles, is it complete - i.e. should it link?
It's undefined behavior, so technically, we can't say. In
practice, I can't imagine a system where it would link.
* Should the fact that A has a pure virtual destructor influence
whether or not B's destructor is called in the context of exception
'a'?
No. Pure virtual has no influence on anything here. By the
time we get into B's constructor, A has been fully constructed,
so its destructor must be called.

Typically, the compiler will not detect that the code after the
declaration of b is unreachable, nor that in fact, the complete
program will never call the destructor of B, and will generate a
call to A::~A in the destructor of B, which on most systems will
be sufficient to make the link fail unless there is a definition
somewhere.
* Have either of the above two questions different answers if one
looks from the perspective different C++ standards vintages?
No.

--
James Kanze (Gabi Software) email: ja*********@gmail.com
Conseils en informatique orientée objet/
Beratung in objektorientierter Datenverarbeitung
9 place Sémard, 78210 St.-Cyr-l'École, France, +33 (0)1 30 23 00 34

Jun 10 '07 #3

This discussion thread is closed

Replies have been disabled for this discussion.