Use-cases of pure virtual functions with body?

I recently came to know that in C++ pure virtual functions can optionally have a body.

What are the real-world use cases for such functions?


Solution 1:

The classic is a pure virtual destructor:

class abstract {
  public: 
    virtual ~abstract() = 0;
};

abstract::~abstract() {}

You make it pure because there's nothing else to make so, and you want the class to be abstract, but you have to provide an implementation nevertheless, because the derived classes' destructors call yours explicitly. Yeah, I know, a pretty silly textbook example, but as such it's a classic. It must have been in the first edition of The C++ Programming Language.

Anyway, I can't remember ever really needing the ability to implement a pure virtual function. To me it seems the only reason this feature is there is because it would have had to be explicitly disallowed and Stroustrup didn't see a reason for that.

If you ever feel you need this feature, you're probably on the wrong track with your design.

Solution 2:

Pure virtual functions with or without a body simply mean that the derived types must provide their own implementation.

Pure virtual function bodies in the base class are useful if your derived classes wants to call your base class implementation.

Solution 3:

One reason that an abstract base class (with a pure virtual function) might provide an implementation for a pure virtual function it declares is to let derived classes have an easy 'default' they can choose to use. There isn't a whole lot of advantage to this over a normal virtual function that can be optionally overridden - in fact, the only real difference is that you're forcing the derived class to be explicit about using the 'default' base class implementation:

class foo {
public:
    virtual int interface();
};

int foo::interface() 
{
    printf( "default foo::interface() called\n");
    return 0;
};


class pure_foo {
public:
    virtual int interface() = 0;
};

int pure_foo::interface()
{
    printf( "default pure_foo::interface() called\n");
    return 42;
}

//------------------------------------

class foobar : public foo {
    // no need to override to get default behavior
};

class foobar2 : public pure_foo {
public:
    // need to be explicit about the override, even to get default behavior
    virtual int interface();
};

int foobar2::interface()
{
    // foobar is lazy; it'll just use pure_foo's default
    return pure_foo::interface();
}

I'm not sure there's a whole lot of benefit - maybe in cases where a design started out with an abstract class, then over time found that a lot of the derived concrete classes were implementing the same behavior, so they decided to move that behavior into a base class implementation for the pure virtual function.

I suppose it might also be reasonable to put common behavior into the pure virtual function's base class implementation that the derived classes might be expected to modify/enhance/augment.

Solution 4:

One use case is calling the pure virtual function from the constructor or the destructor of the class.