Topic: VC++ virtual destructor


Author: rfg@netcom.com (Ronald F. Guilmette)
Date: Sun, 20 Feb 1994 20:15:55 GMT
Raw View
In article <9404712.7420@mulga.cs.mu.OZ.AU> fjh@munta.cs.mu.OZ.AU (Fergus Henderson) writes:
>kitk@mudshark.sunquest.com (Kit Kauffmann) writes:
>
>>(Posted for Greg Peto [gpeto@mudshark.sunquest.com] by Kit Kauffmann)
>>
>>For example the code:
>>        class A
>>        {
>>        public:
>>           virtual ~A() = 0;
>>        };
>>
>>        A a;
>>does not generate an error in MSVC.
>
>If that is indeed the case, then it is definitely a bug in MSVC.
>class A is an abstract class since it contains a pure virtual
>destructor, and it's illegal to create an object of an abstract class.

Just a trivia question... is there unambiguous wording in the current
draft that says that a declaration like `A a;' "creates an object"?

--

-- Ron Guilmette, Sunnyvale, CA ---------- RG Consulting -------------------
---- domain addr: rfg@netcom.com ----------- Purveyors of Compiler Test ----
---- uucp addr: ...!uunet!netcom!rfg ------- Suites and Bullet-Proof Shoes -




Author: kitk@mudshark.sunquest.com (Kit Kauffmann)
Date: Thu, 10 Feb 1994 17:34:45
Raw View
(Posted for Greg Peto by Kit Kauffmann)

>From: Scott Turner <pkt@lpi.liant.com>
>Subject: None
>To: gpeto@mudshark.sunquest.com

Thank you Scott for copying me via e-mail.

>In article <kitk.241.001000C0@mudshark.sunquest.com>,
>kitk@mudshark.sunquest.com (Kit Kauffmann) wrote:
>
>> Posted By Kit Kaufmann for Gregory J. Peto:
>>
>> I am posting an e-mail thread of correspondance with a member of Microsoft's
>Develper Relations Group (DRG).
>...
>> >| Problem:
>> >|
>> >| Visual C++ v1.5 accepts declaration:
>> >|
>> >| class A
>> >| {
>> >| public:
>> >|    virtual ~A() = 0;
>> >| };
>> >|
>> >| class B : public A
>> >| {
>> >| };
>
>A pure virtual function (such as A::~A()) may or may not be defined
>somewhere in a program.

After sending off my post I remember running into this before with GNU and

other C++ compilers. Any class derived from a class with a virtual destructor

must have a destructor (explicit or compiler generated). This point conceded.

>The compiler automatically generates a destructor for class B.  The
>last thing this destructor does is call the destructor for its A part,
>i.e. A::~A().  If the program contains a definition of A::~A() then all
>will work fine.  If not, then there will be a link-time error.
>
>> >| 1) If MSVC accepts making the class A destructor "pure" and child class B does not
>> >| provide a version of pure virtual function from A the MSVC compiler shouldgenerate an
>> >| error when trying to instantiate an object of class B because B is an "abstract
>> >| class".
>
>A destructor is a special case in which the child class need not explicitly
>provide the member function by declaring and defining it.  The compiler
>automatically provides one.  B is not an abstract class; there should be
>no error message.

It seems from code, I show below, that neither A nor B is treated as abstract

by MSVC. However, I do not see why they are not.

>> How can the compiler require a "pure" virtual function to exist?
>
>> >| 2) MSVC Should never generate reference to A::~A() since this is a "pure"
>function.
>
>Not so. Any function that's declared pure virtual may be called with an
>explicit-qualifier to suppress the virtual mechanism.  For example,
>
>    class A {
>    public:
>        virtual void foo() = 0;
>    };
>    void A::foo() { }
>    class B {
>        B() { A::foo(); } // circumvents virtual table
>    };

Your code as listed here will not compile. However it will compile as:

class A {
public:
    virtual void foo() = 0;
};
void A::foo() { }
class B {
     B(A * a) {
      a->A::foo();  // circumvents virtual table
     }
};

I will concede that making a virtual function "pure" does not mean it does not

exist. However it does make class A above an abstract class. Trying to

instantiate A (with foo function) will generate an error.

Why is A not an abstract class if it contains a "pure" virtual destructor

function? For example the code:
        class A
        {
        public:
           virtual ~A() = 0;
        };

        A a;
does not generate an error in MSVC. In affect the compiler is ignoring the
"= 0" text. This still seems inconsistent to me. The compiler should at least

generate a warning that the "= 0" has no affect and the destructor is still

required to explicitly exist, or MSVC should treat class A as abstract as it

would for any other class with a pure virtual function.

I did not look in Stroustrup's books for a good quote, but Scott Meyers in

"Effective C++" on page 47 states "the compiler will generate a call to <the

virtual destructor function> even though the class is abstract." If the class

is abstract you should not be allowed to explicitly instantiate it.

>In this case the destructor for B needs to call the destructor for A in
>the non-virtual sense.  MSVC is definitely correct on this point.
>
>> You state that declaring a pure virtual destructor should force the class
>> (class B in my example) to be treated as "abstract".
>
>She didn't say that.

You are right. She stated "Declaring a virtual destructor to be pure simply

forces the class to be abstract" in reference to A, not B. However, as my code

with "A a" above shows, MSVC is not treating class A as abstract either.

>> Your statement that, "Pure virtual destructors must still be defined" does
>> not make sense.
>
>Pure virtual destructors are possible, but are not very useful just because
>they invariably need to be defined.

You apparently can "declare" a pure virtual function, but they really are "not

possible" because they are required to exist (unlike other pure virtual

functions). If pure virtual destructors are required to be explicitly defined

and the class is not treated as abstract, why does the standard even allow them

to be declared? And why does the compiler not at least generate a warning

message that it has no effect?

Gregory J. Peto
gpeto@mudshark.sunquest.com



Kit Kauffmann   kitk@mudshark.sunquest.com (Internet)
                73363,447 (Compu$erve)
                (801) 277-5790




Author: fjh@munta.cs.mu.OZ.AU (Fergus Henderson)
Date: Wed, 16 Feb 1994 01:12:34 GMT
Raw View
kitk@mudshark.sunquest.com (Kit Kauffmann) writes:

>(Posted for Greg Peto [gpeto@mudshark.sunquest.com] by Kit Kauffmann)
>
>For example the code:
>        class A
>        {
>        public:
>           virtual ~A() = 0;
>        };
>
>        A a;
>does not generate an error in MSVC.

If that is indeed the case, then it is definitely a bug in MSVC.
class A is an abstract class since it contains a pure virtual
destructor, and it's illegal to create an object of an abstract class.

--
Fergus Henderson - fjh@munta.cs.mu.oz.au




Author: brent@oceania.com (Brent Milnor)
Date: Thu, 17 Feb 1994 00:24:19 GMT
Raw View
Fergus Henderson <fjh@munta.cs.mu.OZ.AU> wrote:
>kitk@mudshark.sunquest.com (Kit Kauffmann) writes:
>
>>(Posted for Greg Peto [gpeto@mudshark.sunquest.com] by Kit Kauffmann)
>>
>>For example the code:
>>        class A
>>        {
>>        public:
>>           virtual ~A() = 0;
>>        };
>>
>>        A a;
>>does not generate an error in MSVC.
>
>If that is indeed the case, then it is definitely a bug in MSVC.
>class A is an abstract class since it contains a pure virtual
>destructor, and it's illegal to create an object of an abstract class.
>
I tried the code in MSVC version 1.5 and got an appropriate error message:
    error C2259: 'A' : illegal attempt to instantiate abstract class


Brent
--
Brent Milnor
brent@oceania.com
Opinions are my own.