Question

I just learned to my amazement that the following is legal C++

struct A {
  void foo(int) const = 0;  // pure virtual
  // ...
};
void A::foo(int) const { /* ... */ }

What are sensible use cases for this? I.e. when would A::foo ever be called and why is this the correct/best implementation? Are there any differences here between C++03 and C++11?


Okay, there was a previous question (which I didn't find) with the same intention. However that was pre C++11. So my last question remains valid.

Was it helpful?

Solution

What are sensible use cases for this?

If the function has a sensible default implementation, or a partial implementation of whatever is relevant to the base class, but you still want to force derived classes to override it, that's a good place to put it.

Also, as noted in the comments, you might want to force a class with no pure virtual functions to be abstract. You can do this by making the destructor pure virtual; but the destructor must have a body, whether or not it's pure virtual.

when would A::foo ever be called?

It can only be called non-virtually; for example:

struct B : A {
    void f(int i) const {
        A::foo(i);    // non-virtual call
        // Do the B-specific stuff
    }
};

why is this the correct/best implementation?

The alternative would be to invent a new name for the partial/default implementation, in addition to an unimplemented pure virtual function.

Are there any differences here between C++03 and C++11?

No.

OTHER TIPS

The canonical use-case is to mark a class as abstract by providing a pure-virtual destructor - which MUST have an implementation.

It's been the rule since before C++98.

Of course it is legal. Pure virtual functions are meant that instance of that class in which it declared can`t be instantiated, not that it can`t has an implementation.
It`s like interface in C#, for example.

What opportunities it provides?
1. client can use default implementation.
2. classes with pure virtual destructor no longer raise linker error (when you apply delete to pointer to base class: destructors of derived class are invoked, and after that destructor of base class is invoked, if you ommit implementation - linker will raise an error).

References: need for implementation in pure virtual method is described in depth in the book "Effective C++" by Scott Myers

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