Pure Virtual

In C++, you declare a virtual function to be "PureVirtual" like so:

        class Before {
                virtual void f(); // Normal "virtual"
        };

class After { virtual void f() = 0; // *Pure* "virtual". };

No one knows why you use "= 0" rather than some other notation. It's not explained in TheDesignAndEvolutionOfCpp, so it's best left un-questioned. =)

Probably because "virtual foo(args)=0" is a syntax that was formerly disallowed by the language; so adding it to the grammar wouldn't break any existing programs. Adding a keyword such as "abstract" on the other hand, is more likely to break existing code. Might explain a bunch of other syntactic hacks in CeePlusPlus, such as ClassName() being the name of the constructor and ~ClassName() being the name of the destructor. This syntactic FuBar has caused all sorts of grief; as it's OneMoreThing? to change when you rename a class (OnceAndOnlyOnce), and also because it makes providing constructors for anonymous classes impossible. JavaLanguage inherited this silliness; where it causes even more problems due to the increased importance of InnerClasses and AnonymousInnerClasses. Nowadays, Java has YetAnotherSyntax? to initialized anonymous classes...


Wild guess: The function pointer in the vtbl of the abstract base class is NULL. (And "NULL" is really "(long)0" anyway.)

I've heard that before, but it doesn't really satisfy me, because a vtbl is a run-time entity, and the error is compile-time. You could say that the internal representation of what is to become the vtbl uses "0", but that kind of implementation detail is irrelevant to users of C++ (and, worse, it encourages MagicNumbers -- the null itself).

Much to my preference would be to use a keyword, for example "pure". I know adding new keywords is dangerous, but as long as you only add meaning for the word within a certain context then nothing is hurt. Even if that is arguable, I consider the PureVirtual notation to use a keyword: "=[:space:]*0"

Do you see why it's best left unquestioned?


GCC, at least 2.8.x and 2.9.x, has a function called __pure_virtual or something like that, which if called does something useful (raises an exception or aborts the program). While calling a pure virtual shouldn't be possible in a correctly built C++ program, it could happen if a base class function goes from implemented to pure virtual, and a program that uses it isn't recompiled. See also FragileBinaryInterfaceProblem. -- ScottJohnson

FWIW, Microsoft VisualCeePlusPlus has a similar function, called _purecall(), which "traps" inadvertent calls to pure virtual functions.

Using CeePlusPlus it is rather easy to "call" a pure virtual function if you export the this-pointer from a constructor or from the destructor:

 class Base;

void f(Base&);

class Base { public: Base(void) { f(*this); } virtual void g(void) = 0; };

void f(Base& b) { b.g(); }

class Derived : public Base { public: Derived(void) : Base() { /* empty */ } virtual void g(void) { /* ... */ } };

int main(int argc, char* argv[]) { Derived d; // BOOM! return 0; }

Also see PureVirtualFunctionCalled.
For comparison, in JavaLanguage, PureVirtual methods are called "abstract methods", are declared with the "abstract" keyword, and have no body. Classes which contain abstract methods must themselves be declared abstract.
        class Before {
                void f() { /* stuff happens here */ } // Normal "virtual"
        }

abstract class After { abstract void f(); // *Pure* "virtual". }

CategoryPolymorphism

EditText of this page (last edited July 27, 2010) or FindPage with title or text search