Starting to use PC-Lint on an existing code base (fear and trepidation).
One thing that it complains about is the following:
class IBatch { public: virtual void StartBatch() =0; virtual int CommitBatch() =0; };
Which when another class derives from this to use it like an interface
base class 'IBatch' has no destructor
So, the question: when you create Interface classes like the above, do you always include a virtual destructor? Why? (is it a style or a coding error?)
EDIT: Should have said that I do not expect or want the user of IBatch to destruct, they are a consumer of a service only, through this interface to some external implementing class (if that would make a difference)
A destructor is a member function that is invoked automatically when the object goes out of scope or is explicitly destroyed by a call to delete . A destructor has the same name as the class, preceded by a tilde ( ~ ).
Class members that are class types can have their own destructors. Both base and derived classes can have destructors, although destructors are not inherited. If a base class A or a member of A has a destructor, and a class derived from A does not declare a destructor, a default destructor is generated.
Destructors cannot be declared const , volatile , const volatile or static . A destructor can be declared virtual or pure virtual . If no user-defined destructor exists for a class and one is needed, the compiler implicitly declares a destructor.
Can there be more than one destructor in a class? No, there can only one destructor in a class with classname preceded by ~, no parameters and no return type.
A base class destructor should be either public and virtual, or protected and nonvirtual.
(Herb Sutter, Guru of the Week #18: "Virtuality")
Coding error - The destructor for your derived class will never get called if called via pointer to base class.
When you implement IBatch
and you refer to your derived class by a pointer to a base class (pointer to IBatch
) and you call delete
on that pointer to base class you might end up with memory leak because the destructor for your derived class will never get called.
The basic rule is when a class has at least one virtual
method it needs to have virtual
destructor.
class IBatch { public: virtual void f() = 0; }; class A : public IBatch { public: void f() {} ~A() {} }; IBatch * a = new A(); a->f(); // calls A::f() delete a; // calls IBatch::~IBatch() not A::~A()
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With