Let us assume I have two classes:
class Base{};
class Derived: public Base{};
none has d'tor, in this case if I declare about variables:
Base b;
Derived d;
my compiler will produce for me d'tors, my question is, the default d'tors of the b and d
will be virtual or not?
my question is, the d'tors of the b and d will be virtual or not
No, they won't. If you want a virtual destructor, you will have to define your own, even if its implementation is exactly the same as that which would be supplied by the compiler:
class Base {
public:
virtual ~Base() {}
};
The destructors of Base
and Derived
will not be virtual
. To make a virtual
destructor you need to mark it up explicitly:
struct Base
{
virtual ~Base() {}
};
Actually there's now only one reason to use virtual destructors. That is to shut up the gcc warning: "class 'Base' has virtual functions but non-virtual destructor". As long as you always store your allocated objects in a shared_ptr
, then you really don't need a virtual destructor. Here's how:
#include <iostream> // cout, endl
#include <memory> // shared_ptr
#include <string> // string
struct Base
{
virtual std::string GetName() const = 0;
};
class Concrete : public Base
{
std::string GetName() const
{
return "Concrete";
}
};
int main()
{
std::shared_ptr<Base> b(new Concrete);
std::cout << b->GetName() << std::endl;
}
The shared_ptr
will clean up correctly, without the need for a virtual destructor. Remember, you will need to use the shared_ptr
though!
Good luck!
my question is, the d'tors of the b and d will be virtual or not
Short answer : Nopes!
They will NOT be virtual.However, if you declared(and defined) a virtual dtor in Base, then the derived's dtor would be automatically virtual. HTH.
How can they be virtual unless you explicitly make them as virtual
Just to add one more example to Daniel Lidström's answer
As long as you always store your allocated objects in a shared_ptr, then you really don't need a virtual destructor.
If one uses a shared_ptr like this:
std::shared_ptr<Base> b(new Concrete);
Then the Concrete destructor and the Base destructor are called on destruction of the object.
If one uses a shared_ptr like this:
Base* pBase = new Concrete;
std::shared_ptr<Base> b(pBase);
Then only the Base destructor is called on destruction of the object.
This is an example
#include <iostream> // cout, endl
#include <memory> // shared_ptr
#include <string> // string
struct Base
{
virtual std::string GetName() const = 0;
~Base() { std::cout << "~Base\n"; }
};
struct Concrete : public Base
{
std::string GetName() const
{
return "Concrete";
}
~Concrete() { std::cout << "~Concrete\n"; }
};
int main()
{
{
std::cout << "test 1\n";
std::shared_ptr<Base> b(new Concrete);
std::cout << b->GetName() << std::endl;
}
{
std::cout << "test 2\n";
Base* pBase = new Concrete;
std::shared_ptr<Base> b(pBase);
std::cout << b->GetName() << std::endl;
}
}