Search code examples
c++abstract-classvirtual

Why would I want to implement virtual functions without implementation in an abstract class?


I am sorry but I have to ask a stupid question. I understand the benefit of implementing an abstract class as such. If I have virtual function with a basic implementation that is always called in cases when the derived classes don't have a specific implementation there is definitely a benefit, e.g. virtual void ImplementedVirtFunc() {//do something basic}

What I don't quite get is what is the benefit of implementing a purely virtual function such as virtual void VirtFunc() = 0;

In this case my derived classes need to implement the specialisized function anyhow if they need it. But I could straight forwardly just implement it there and omit the virtual void VirtFunc() = 0 line in my abstract class.

So is there a specific benefit for implementing virtual void VirtFunc() = 0 that I don't see?

Please forgive me this stupid question. I started to learn C++ this January and I am still have a long way to go to understand all the subtleties...


Solution

  • virtual void f();     // virtual member function
    virtual void g() = 0; // pure abstract member function
    

    A class with at least one pure virtual member function is an abstract class, and cannot be constructed itself, which is often desired (only non-abstract, "concrete" if you will, derive classes should be able to be constructed);

    struct Abstract {
       virtual void g() = 0;
    };
    
    struct NonAbstract {
        virtual void f() {}
    };
    
    int main() {
        NonAbstract na{}; // OK
        Abstract a{};     // Error: cannot declare variable 'a' 
                          //        to be of abstract type 'Abstract'
    }
    

    Abstract classes are typically used polymorphically, to allow dynamic dispatch to derived object methods:

    struct Derived : public Abstract {
        void g() override {}  // #1
    }
    
    void h(Abstract const& obj) {
        obj.g();  // dynamic dispatch
    }
    
    int main() {
        Derived d{};
        h(d);  // Will result in invoke #1
    }