Do you mean that, if I have, virtual ~Base(), I should (Or, must?) make virtual ~all-otherDerived(), also?
I am confused, this worked fine without adding a virtual ~Derived2():
Output:Code:#include <iostream> using namespace std; class Base2 { public: virtual ~Base2() { cout << "~Base2()" << endl; } }; class Derived2 : public Base2 { public: ~Derived2() { cout << "~Derived2()" << endl; } }; int main() { Base2* basePtr = new Base2; delete basePtr; basePtr = new Derived2; delete basePtr; return 0; }
~Base2()
~Derived2()
~Base2()
This is another issue. You don't need to add the virtual keyword to subsequent functions in derived classes if the function is virtual in the base. They will be virtual anyway.
But for clarity, I always add virtual to all functions.
Try making the Base destructor pure virtual and omitting the one in Derived. The code won't compile if you create a Derived (or shouldn't).
It should and would. The implicitly created destructor is a valid override of the pure function.Try making the Base destructor pure virtual and omitting the one in Derived. The code won't compile if you create a Derived (or shouldn't).
The code wouldn't link, though, because you still need an implementation of Base::~Base, even if you declared it pure.
Code:inline Base::~Base() {}
All the buzzt!
CornedBee
"There is not now, nor has there ever been, nor will there ever be, any programming language in which it is the least bit difficult to write bad code."
- Flon's Law
That seems strange but magical also, anyway, less work on programmer's part.
That is unclear to me, besides, testing that it links or not, I am unable to explain why it is happening? And what is inline doing here?The code wouldn't link, though, because you still need an implementation of Base::~Base, even if you declared it pure.
Code:inline Base::~Base() {}
Why? The compiler generates a destructor - it has to. Why should this destructor be any different from an explicitly defined constructor in its ability to override the base version?That seems strange but magical also
As for the link issue, I'll try to explain.
This is the basic situation. Now the compiler generates a destructor for Derived. Including the implicit call to the base, the final version of a destructor looks like this:Code:struct Base { virtual ~Base() = 0; }; struct Derived : Base { }; int main() { Derived d; }
See that call to Base::~Base()? It must be there, because the base class must be destructed, no matter what. So the call is generated. The linker then looks for Base::~Base(), but it won't find it, because there is none. The explicit declaration in Base means that the destructor isn't generated, but you don't define it either.Code:Derived::~Derived() { // Put code from the user-defined destructor here. // Put calls to members' destructors here. // Put calls to base destructors here. Base::~Base(); // Many compilers end with this: return this; }
So you have to define it explicitly. Since Base has nothing special to do, it's empty. It still has to be there.
As for the inline, it allows the compiler to inline non-virtual calls to the destructor. And because all calls to the destructor are non-virtual (virtual calls aren't possible due to it being pure), that's a good idea. It means the compiler can then optimize the destructor away completely.Code:Base::~Base() {}
All the buzzt!
CornedBee
"There is not now, nor has there ever been, nor will there ever be, any programming language in which it is the least bit difficult to write bad code."
- Flon's Law
I must have missed it, but why are you storing a pointer to Base in Derived?
Thanks CornedBee.
Elks, Do you remember the other situation in different thread?
Array of something is-a something. Similar situation here.
I was just looking for ways to get a cosmic type. I didn't know what is cosmic about it. But laserlight has told this to me.
So now a Derived HAS-A and IS-A Base? I think I'd roll my own code and stop using generated cruft like that. Or maybe use a language with more elegant support for calling web services (maybe Java, perl, python?).
Last edited by medievalelks; 05-30-2008 at 08:09 AM.