Why can we virtual destructors but can't have virtual constructors? I have searched like anything. I got confused a lot after reading few articles on web. Please explain with some good example. Thanks in advance.

Recommended Answers

All 5 Replies

Why would you have a virtual constructor? The reason you use virtual is to create a virtual table so that when a function is called from a pointer to a base it will call the function of the derived object that was stored in that pointer. Since you have to explicitly call the constructor when you create an derived object there is no reason to have it virtual. The destructor needs to be virtual though since you are calling destroy on the base pointer and the program needs to know what derived object destructor to use.

Hi

Let's start by defeing the key word virtual it self.

virtual method is a method whose behavior can be overridden within an inheriting class by a function with the same signature.

So, when we have virtual constructor means in future it is possible to re-define, but a fully constructed object is required inorder to invoke virtual member function of class. As we know constructor gets called during object getting constructed, If constructor is marked as virtual mean that it also required fully constructed object to invoke but object is still under construction.

when making base class destructor virtual guarantees that the object of derived class is destructed properly (The correct destructor is called).

Here an example :

#include <iostream>

using namespace std;

class Base 
{
    public:

    Base () 
    {std::cout << "Base Class Ctor" << std::endl;}  // Constructor

    virtual ~Base () {std::cout <<"Base Class Dtor" << std::endl;} // Destructor 

    virtual void Display ()
    {
        std::cout << "Display Base" << std::endl;
    }
    void Print ()
    {
        std::cout << "Print Base" << std::endl;
    }
};

class Derived : public Base
{
    public:

    Derived () {std::cout << "Derived Class Ctor" << std::endl;} // Ctor
    virtual ~Derived () {std::cout << "Derived Class Dtor" << std::endl;}// Dtor
    void Display ()
    {
        std::cout << "Display Derived" << std::endl;
    }
    void Print ()
    {
        std::cout << "Print Derived" << std::endl;
    }
};

int main ()
{

   Base *b = new Derived ();

   b->Print();
   b->Display();   
   delete b;

}

The output is as below :

Base Class Ctor
Derived Class Ctor
Print Base ==>
Display Derived ==> here the difference betwenn virtual & non virtual method
Derived Class Dtor
Base Class Dtor

Why? Because you may have something in that class constructor that the subclasses do not need to know/worry about doing or how is it done

Using the Prototype Pattern you could create an HTTPServer that allows you to implement (in a subclass) the HTTP methods ( get(), post(), delete(), options(), ...).

In the HTTPserver you would implement all the socket handling, header from body separation, request type identification, etc. This for sure needs a constructor (you could use a method that is to be called when the server is created, but that's what a constructor is for).

The subclasses, a RESTWebService, should implement only the HTTP methods and not worry about how to handle the things the superclass handles the connectivity and header parsing.

Sorry if you expected some bunch of C++ code, but you asked a WHY question :P

@serpi90 I think you are confusing how derived objects get created. If you have:

class A
{
    A() { /*do super complicated stuff in here to set up A*/ }
    virtual void Foo();
};

Class B : public A
{
    B() : A() { /*set up the B object here*/  }
    void Foo();
};

Class C : public A
{
    C() : A() { /*set up the C object here*/  }
    void Foo();
};

As you can see the derived object calls the base class constructor which handles constructing the base part of the derived object and then the B constructor takes care of setting the stuff up that belongs to B. The point of marking function virtual is so you can do this:

vector<A*> data;
data.push_back(new B());
data.push_back(new C());

for (auto& e : data)
    e->someFunc();

Here the right function gets called in the for loop. As you can see though we still have to construct the object with the right constructor.

@NathanOliver oh, now i do understand the question. Thank you for the explanation.

Be a part of the DaniWeb community

We're a friendly, industry-focused community of developers, IT pros, digital marketers, and technology enthusiasts meeting, networking, learning, and sharing knowledge.