Can a class still be pure abstract if it has a non-pure destructor?
Asked Answered
D

6

3

I am working on an exercise which asks me to take a base class Rodent and make it a pure abstract class. My understanding of a pure abstract class is that it acts as an interface and only contains pure virtual functions. Although this is an easy exercise I have a problem with the solution provided by the book:

class Rodent
{
    public:

    virtual ~Rodent() {cout << "Destroy rodent" << endl;}
    virtual void run() = 0;
    virtual void squeak() = 0;
};

As you can see the author has added a dummy definition for the destructor. Does the adding of this definition not mean that this is an abstract class and not a 'pure' abstract class?

Dhiman answered 28/9, 2011 at 15:49 Comment(2)
I understand, I wanted to know if its still 'pure' abstract.Dhiman
The least interesting bit of the question is the fact that pure abstract class is not a C++ concept, so it will greatly depend on what your definition of that term is (Compare with: pure virtual function that is defined in the standard to have a precise meaning)Bathymetry
B
6

An Abstract class must contain atleast one pure virtual function.

Your class already has two pure virtual functions run() and squeak(), So your class is Abstract because of these two pure virtual functions.

You cannot create any objects of this class.

EDIT:

A pure abstract class, is a class that exclusively has pure virtual functions (and no data). Since your destructor is not pure virtual your class is not Pure Abstract Class.

Blackjack answered 28/9, 2011 at 15:52 Comment(6)
I am agree with you this is still an abstract class, your definition is quite complete but for the sake of completion: A virtual function is called "pure" when it has no definition, if it has a definition is just a virtual function ( method really ). Thanks!Hebetic
Yes, pure virtual functions can have definitions, but the destructor in this example is not pure. The question isn't about whether the class is abstract. It's about whether it's pure abstract.Delete
@thamurath: That is not correct. Pure virtual functions can have a definition, just that C++ does not allow the definition to be inline to the class. Presence or absence of the function definition does not change the fact whether the function is pure virtual or not.Blackjack
The question is about "pure abstract" classes, not pure virtual functions nor abstract classes.Avert
@Als OP asked about PURE abstract, not just abstract.Henslowe
@thamurath: That is not precisely true. A member function is pure virtual if it is declared with the pure-specifier = 0. The difference with your definition is that a pure virtual function can have a definition: struct test { virtual void f() = 0; }; void test::f() {} is perfectly valid (and usable) code. This is not just a virtual function as the presence of f in test inhibits the instantiation of objects of type test --which is what pure virtual means.Bathymetry
C
3

A destructor is required for every class by the rules of C++. If you don't provide one, the compiler will generate one for you.

In my opinion this is still a pure abstract class, because the destructor is an exception to the rule.

Crony answered 28/9, 2011 at 15:52 Comment(5)
What if the destructor sets a global variable? What if the constructor opens a file for logging? Of course this is a very silly question of definitions, but within that context, I am not sure I agree with you :-)Avert
@Nemo: it's solely a question of what you think a "pure abstract class" should imply. If you want to use that term to designate classes that (in addition to other constraints) have do-nothing destructors, then define it that way. Mark, and the author of the questioner's textbook, define it another way. That's the great thing about writing a book, you get to say what the technical terms in it mean :-)Unreal
What wrong with using "all members are pure virtual functions"?Clarita
@JoeGauterin, the destructor is a member and it can't be pure virtual, because the rules of C++ won't allow it. Otherwise your definition is great.Crony
@Mark Ransom: Destructors can be pure virtual - struct foo{ virtual ~foo()=0;}; inline foo::~foo(){}Clarita
S
2

The virtual keyword means something a bit different for destructors. When a base class's dtors are virtual, it means all dtors in the inheritance hierarchy are called. You can't really override it as such.

Usually you'd expect it to be empty:

class Rodent {
public:
  virtual ~Rodent() {}
  virtual void run() = 0;
  virtual void squeak() = 0;
};

I see very little difference. It is possible that because the empty body is a no-op the compiler can ignore it through some language lawyer statute.

I don't think you'd confuse anyone by calling yours pure virtual.

Scleroprotein answered 28/9, 2011 at 15:56 Comment(2)
The empty body of the destructor is useful because it will be called by all derived classes; if it's known to be empty at compile time the compiler can optimize it away.Crony
@MarkRansom I see why it is good, useful, etc. Whether there is a strict definition per the spec is one thing and I have no answer to that. I don't think there is a conceptual difference between to two in terms of understanding what is happening, though.Scleroprotein
L
2

As far as I understand, the C++ standard does not specify a pure abstract class. The C++0x (n3290) however specifies abstract class.

10.4/2 A class is abstract if it has at least one pure virtual function.

The pure abstract class is a conventional term and describes an abstract class that;

  • does not have of data members
  • does not have of any non-pure virtual functions
  • does not have of any concrete functions

specified by user.

So, according to this convention, the class Rodent is not a pure abstract class.

Lysozyme answered 28/9, 2011 at 16:0 Comment(0)
R
2

Consider implementing your interface like so

class Rodent {
public:
  virtual ~Rodent() = 0;
  virtual void run() = 0;
  virtual void squeak() = 0;
};
inline Rodent::~Rodent() {}

Specifying your destructor as pure virtual and inlining the implementation avoids the following warning in MSVC2010 when exporting subclasses:

warning C4275: non dll-interface class 'A' used as base for dll-interface class 'B'
Renwick answered 28/9, 2011 at 16:50 Comment(0)
S
1

Yes, it is not a pure class anymore. A pure, abstract class has no functionality in it, it just provides a framework. cout is functionality.

Sarisarid answered 28/9, 2011 at 15:55 Comment(0)

© 2022 - 2024 — McMap. All rights reserved.