Question

Pure virtual functions are a must-have property for abstract base classes. So no implementations should be made, which is very intuitive to understand. But Recently I came to know that pure virtual functions can still be defined later and be invoked statically(not by object instances). I can't think up a reason for this. If one virtual function is defined as pure, then what's the reason to implement it?

class A{
public:
    ...
    virtual void interface() = 0; //Pure Virtual functions
    ...
}

void A::interface() //Implementation
{
    cout<<"This the implementation for A interface";
}

I am curious about the logic behind this. Why is c++ designed like this way?

Was it helpful?

Solution

It might make sense to have a "default" implementation, which concrete classes can use if it's useful to them. They still need to override it, but can call the base-class version non-virtually:

struct B : A {
    void interface() {
        A::interface(); // call the default implementation
        // and maybe do some B-specific things too
    }
};

OTHER TIPS

I can't think up a reason for this. If one virtual function is defined as pure, then what's the reason to implement it?

The purpose of a pure virtual function is not to prohibit definitions. It is to mark the class as uninstantiable.

Providing a definition may be useful for deriving classes:

struct A
{
   virtual void foo() = 0;
};

void A::foo()
{
   /* some common logic here */
}

struct B : A
{
   virtual void foo() overrides
   {
      bar();
      A::foo();
   }

   void bar();
};

struct C : A
{
   virtual void foo() overrides
   {
      baz();
      A::foo();
   }

   void baz();
};

A pure virtual function simply means that the function must be overidden by all derived classes it does not mean that the function cannot/should not have a implementation of its own. Two most obvious cases for such a pure virtual function having implementation are:

  • A Derived class implementation can call Base class implementation
  • Sometimes you would want a base class to be made abstract but there is no method which you can mark as pure virtual in such a case a destructor is most obvious choice but in such a destructor still needs a implementation.

interface() = 0 means derived classes must provide an implementation, so the definition effects derived classes, but the base class is permitted to have an implementation of the method so that derived classes can always call base::interface().

You apparently completely misunderstood the meaning of the term "statically" in this context.

Yes, pure virtual functions can still have bodies, i.e. they can still be defined.

And no, you cannot invoke such function "without an object instance", as you seem to incorrectly believe. A pure virtual function with a body is still a non-static member function. It still requires an object instance to be invoked.

When someone says that such function can be invoked "statically", it means that it can be called directly, without using virtual dispatch mechanism. Function calls that go through virtual dispatch are sometimes called "virtual calls" or "dynamic calls", while direct function calls are sometimes called "static calls". The term "static" in this context assumes a completely different meaning, not connected in any way to static member functions.

In C++ language a direct non-virtual (i.e. "static") call can be performed explicitly by specifying a qualified member name in the call. For example, if class B derives from your class A, then inside some method B::foo() you can use the following syntax

void B::foo() {
  A::interface(); // <- qualified method name
}

which performs a direct call to the implementation of A::interface() you provided. For an object b of type B the same kind of call can be performed as

B b;
b.A::interface(); // <- qualified method name

In both cases the call is performed for a specific object (*this in the first example, and b in the second).

Pretty much the same thing happens implicitly when destructors of derived classes call destructors of base class, which is why you will often encounter this situation with pure virtual destructors (i.e. they are declared as pure virtual, yet have a body).

Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top