Click here to Skip to main content
16,016,345 members
Please Sign up or sign in to vote.
5.00/5 (2 votes)
See more:
Hello, guys:
Recently, I got a question, about pure virtual class. Sometimes I need to design an interface for my job, looks like:

class CInterface
{
    virtual ~CInterface()=0{}
    virtual void SomeAction()=0;
}

class DerivedA:public CInterface
{
   DerivedA(){}
   ~DerivedA(){}
   void SomeAction()
   {
   cout<<"Action from Derived class A ."<<endl;
   }
}

But what make me confused is that it works well after I change CInterface,like below:
C#
class CInterface
{
    //virtual ~CInterface()=0{}
    virtual void SomeAction()=0;
}


So, my question is, shall I use destructor in a pure virtural class?And when?

Thanks in advance!

[ADD]:

Firstly, thanks a lot to all of you!
Then we should continue about this issue. In my opinion, what we design an interface or a pure virtual class for is use it as an interface or pointer(some address pointed to DerivedA object existed).
1. So, we do it like this:
void SomeFun(CInterface *pt)//we always pass a DerivedA* to pt.
{
pt->SomeAction();//polymorphism 
}

2. Not used like this:
CInterface *pt = new DerivedA();
pt->SomeAction();
delete pt;

Because we don't design CInterface as a 'base' class for DerivedA but only an interface,if so ,we should call it 'DerivedABaseClass' or sth.

To make the class CInterface be a real interface, we only use it as a 'handle' in client classes,we should never allocate or deallocate upon 'CInterface*' pointers.


3. So, I think the destructor in class CInterface should be canceled.

4. Welcome for discussing, anyone make the issue clear will be appreciated.
Posted
Updated 16-Mar-11 14:22pm
v5
Comments
Sergey Alexandrovich Kryukov 17-Mar-11 13:45pm    
After the discussion I decided to up-vote the question by my 5 -- a good one, thank you for asking.
Good to know such delicate details.
--SA
scu_sundy 18-Mar-11 22:50pm    
Thank you.

You only need a destructor if you need to deallocate pointers (or free resources) that were allocated within the pure virtual class itself.
 
Share this answer
 
Comments
scu_sundy 16-Mar-11 20:16pm    
To make the class CInterface be a real interface, we only use it as a 'handle' in client classes,we should never allocate or deallocate upon 'CInterface*' pointers.
So, I don't think the destructor is necessary.
Ozer Karaagac 16-Mar-11 20:41pm    
may be necessary to ensure "virtuality" for destructors within derived classes.
scu_sundy 16-Mar-11 20:57pm    
We use "virtuality" upon some interface functions like 'SomeAction()' int 'CInterface', virtual destructor isn't 'pure' enough when we design an interface class.
Ozer Karaagac 16-Mar-11 21:57pm    
Conceptually, an interface should (only?) define some behaviors (as with COM, pure interface that is all functions are pure virtual). But, in C++, we can utilize a class in which some of its behaviors pre-defined but one is left as pure virtual that is undefined.

Additionally, we can probably pass an interface pointer to a function and we have to delete that object there in that function. All we have a base interface pointer in hand. If we use this pointer to delete and also its dtor is not virtual, derived classes cleanup can't be done.

So virtual dtors may be used but dtors can't be pure virtual because it must be implemented somewhere and dtors can only be implemented within its class.
scu_sundy 16-Mar-11 22:45pm    
Delete a 'handle' in a designed handle class seems not a good idea.
We use 'handle' to implement something only, just like a proxy.
I think you declared the destructor of CInterface as private(default declaration), so that is why your first code did not worked.In the second since you commented it compiler generated the default destructor for you.

But As for as i know you should declare virtual destrucor and in the Interface(Generic Class).The use of this destructor will be explained in this example,
C#
class CInterface
{
public:
    virtual ~CInterface() = 0{};
    virtual void SomeAction()=0;
};
class DerivedA:public CInterface
{
public:
   DerivedA(){}
   ~DerivedA(){cout<<"In Deriveda"<<endl;}
   void SomeAction()
   {
       cout<<"Action from Derived class A ."<<endl;
   }
};
int main()
{
    CInterface* A = new DerivedA;
    delete A;
    return 0;
}

So if you delete A pointer the CInterface destructor will be called automatically by the compiler.if you wont decalre it as virtual or not declared at all thE CInterface destructor will not be called.

As for as i know virtual ~CInterface() = 0; and virtual ~CInterface(); are same in a Interface with only one differance.i.e. If you want to make a class pure virtual and that class is not having any functions then you can make the destructor as pure virtual, so that the whole class become virtual.I hope you understood.
 
Share this answer
 
v2
Comments
Olivier Levrey 16-Mar-11 10:07am    
Your example won't compile. Pure virtual destructors are not allowed in C++. The compiler will search for the destructor's implementation.
Sergey Alexandrovich Kryukov 16-Mar-11 19:35pm    
Not exactly. Pure virtual destructors _are_ allowed in C++.
You should have said: the class may compile, but the statement where such class is attempted to instantiate will not.
--SA
Olivier Levrey 17-Mar-11 4:38am    
I realized I was wrong, sorry for that. I tried to compile using Visual Studio 2008 and I got an error (the compiler searched the implementation of the destructor). But I found on internet that they are allowed in standard C++, which shows (one more time?) that Microsoft C++ compiler isn't always standard...
Sergey Alexandrovich Kryukov 17-Mar-11 12:57pm    
I'm sure MS C++ is not always standard because it has a long history to be not compliant and claimed it should not be. I tried on VS2008 as well; it compiled a class and did not the instantiation. This looks reasonable. I did not check standard. Does it say you can override virtual destructor (from pure virtual in base) and instantiate? That would make full sense.
--SA
Olivier Levrey 17-Mar-11 13:36pm    
http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2005/n1905.pdf
Page 241. paragraph 7.
They just say pure virtual destructors are allowed (my mistake). But I am not sure if this paper is the most recent...
Nemanja already gave the good answer. If your base class doesn't define a virtual destructor and your inherited classes implement a destructor, then you will encounter the problem he described: your derived destructors will not be called if the object you are deleting is not from that exact class (a base class pointer).

To make short I would say: always define a virtual destructor in your base abstract classes.
- If you implement a destructor in a derived type, this destructor will be called in any case.
- If you don't need a destructor in your inherited classes, this will not hurt.
 
Share this answer
 
Comments
scu_sundy 16-Mar-11 10:14am    
thanks!
You are right, always implement a virtual destructor will be a good choice.
Nuri Ismail 16-Mar-11 10:16am    
Good answer, my 5.
Olivier Levrey 16-Mar-11 10:26am    
Thank you Nuri.
scu_sundy 16-Mar-11 10:22am    
I still find something,if in my work, I never place any pointer like CInterface*, what I define and use is DerivedA*, then the virtual destructor in CInterface is not needed, isn't?
Olivier Levrey 16-Mar-11 10:26am    
If you always have a pointer to the "most derived class" then you don't need a virtual destructor. Virtual destructors are needed for polymorphism (see the example given by Nemanja).
Define "works well". The case where the lack of the virtual destructor will bite you looks like:

CInterface* p = new CDerivedA();

...

delete p; // Undefined behavior!!!


If you are using Visual C++, you may end up with a memory leak in that case, but in general it is undefined behavior.
 
Share this answer
 
Comments
Olivier Levrey 16-Mar-11 9:46am    
Correct. My 5. If your base class doesn't define a virtual destructor and your inherited classes implement a destructor, then you will encounter the problem described by Nemanja: your derived destructors will not be called.
scu_sundy 16-Mar-11 10:07am    
It was the answer!!!
Nuri Ismail 16-Mar-11 10:15am    
Good answer, my 5.
scu_sundy 16-Mar-11 10:30am    
Olivier, if no one will define or use CInterface*, the class is only treated as an interface,so the virtual destructor is not needed. I think that's why I see the differences sometimes.
Yusuf 16-Mar-11 11:32am    
Well said
Constructors and destructors are special cases, not just normal methods. Implicitly the standard constructor (the one without parameters) exists always, even if you don't declare or implement it. The same goes, if I remember right, for the destructor. That's why your modified CInterface works.

In a purely virtual class, you can declare them, but you must not. And keep in mind, that all other constructors than the standard constructor may be essential to your interface and then also should be declared.

Edit: And there is one more thing to consider: Any class with purely virtual methods or a purely virtual class cannot be instanciated. A derived class must implement all purely virtual methods, else you cannot create instances of it. Usually you would not be forced to implemant any constructors or destructors. ANy class derived from the original CInterface would be forced to implement both, a class derived from the modified CInterface not. Seen from this angle, it depends upon what you intend.
 
Share this answer
 
v4
Comments
scu_sundy 16-Mar-11 9:34am    
Virtual destructor is necessary to implement polymorphism, I'm not clear that without a destructor,how it works?
[no name] 16-Mar-11 10:24am    
A virtual destructor is needed in order for the destructor of the base class as well as the destructor of the derived class to be called. A purely virtual destructors does not make much sense,

This content, along with any associated source code and files, is licensed under The Code Project Open License (CPOL)



CodeProject, 20 Bay Street, 11th Floor Toronto, Ontario, Canada M5J 2N8 +1 (416) 849-8900